簡體   English   中英

C的讀取(從標准輸入)停止在0x1a字符處

[英]C reading (from stdin) stops at 0x1a character

目前,我正在為原始數據(如jpg等)實現Burrows-Wheeler變換(和逆變換)。 在測試諸如文本文件之類的普通數據時,不會發生任何問題。 但是,當涉及到讀取jpg文件時,例如,它停止讀取字符0x1a(也稱為替代字符)。 我一直在互聯網上尋找不帶OS依賴代碼但沒有結果的解決方案...我想以二進制模式在stdin中讀取,但是我猜這並不容易。 有沒有簡單的方法可以解決這個問題?

碼:

buffer = (unsigned char*) calloc(block_size+1,sizeof(unsigned char));
length = fread((unsigned char*) buffer, 1, block_size, stdin);
if(length == 0){
    // file is empty
}else{
    b_length = length;
    while(length == b_length){
        buffer[block_size] = '\0';
        encodeBlock(buffer,length);
        length = fread((unsigned char*) buffer, 1, block_size, stdin);      
    }
    if(length != 0){            
        buffer[length] = '\0';
        encodeBlock(buffer,length);
    }
}
free(buffer);

正如您所注意到的,您正在以ASCII模式從stdin進行讀取,並且它正在擊中SUB字符(替代,又名CTRL + Z ,又名DOS文件末尾)。

在Windows上,必須使用setmode將模式更改為二進制:

#if defined(WIN32)
#include <io.h>
#include <fcntl.h>
#endif /* defined(WIN32) */

/* ... */

#if defined(WIN32)
_setmode(_fileno(stdin), _O_BINARY);
#endif /* defined(WIN32) */

在Windows以外的平台上,您不會在模式上遇到這種區別。

沒有操作系統依賴性,您將無法執行此操作。 C語言規范說(7.19.3)

在程序啟動時,預定義了三個文本流。

stdin是文本流。 根據您的操作系統,可以使用多種方法來更改現有流的模式或訪問低級流數據,但是您聲稱不需要任何特定於操作系統的代碼。

您必須將文件作為二進制文件打開。

使用類似於

fopen("file", "rb");

您可以使用_setmode將stdin轉換為二進制模式。

還有freopen看到這個問題

使用read()讀取數據。
由於您有興趣從stdin獲取數據,請使用

fd = fcntl(STDIN_FILENO, F_DUPFD, 0);

獲得stdinfd

更多信息在這里

該問題與Windows將0x1a aka CTRL + Z視為EOF的事實有關。 正如Earlz指出的那樣,以二進制模式打開它可以在Windows上解決此問題,也可以在Linux上工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM