[英]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");
使用read()
讀取數據。
由於您有興趣從stdin
獲取數據,請使用
fd = fcntl(STDIN_FILENO, F_DUPFD, 0);
獲得stdin
的fd
。
更多信息在這里 。
該問題與Windows將0x1a
aka CTRL + Z視為EOF
的事實有關。 正如Earlz指出的那樣,以二進制模式打開它可以在Windows上解決此問題,也可以在Linux上工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.