2012-10-17 96 views
1

目前我正在實施原始數據(如JPG等)的Burrows-Wheeler變換(和逆變換)。 當在文本文件等正常數據上進行測試時,不會出現問題。但是當閱讀jpg文件時它停止閱讀字符0x1a又名替代字符。 我一直在尋找通過互聯網的解決方案,不採取操作系統依賴代碼,但沒有結果... 我正在想在二進制模式下讀取stdin,但這不是很容易,我猜。有沒有簡單的方法來解決這個問題?C閱讀(從標準輸入)在0x1a字符停止

代碼:

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); 
+0

您能否發佈演示此問題的代碼? – simonc

+0

代碼太長,無法發佈。基本上我使用fread()從標準輸入讀取,我正在做一個while循環。除非fread讀取了0個字節,否則這個循環會繼續讀取。 – user1745184

+1

請勿發佈整個代碼。只是表明問題的部分。例如。刪除所有轉換代碼並生成一個簡單地從標準輸入讀取的程序。 –

回答

1

您必須打開該文件爲二進制文件。

使用類似

fopen("file", "rb"); 
+0

我正在閱讀stdin,而不是文件。 – user1745184

+0

stdin也是一個文件。 @埃爾茲的建議是正確的。 (至少在微軟的「操作系統」,至少) – wildplasser

+0

它必須在Linux操作系統下編譯和運行... – user1745184

0

使用read()東西在數據讀取。
既然你有興趣從stdin獲取數據,使用

fd = fcntl(STDIN_FILENO, F_DUPFD, 0);

獲得的stdinfd

更多信息here

這個問題與windows treats 0x1a a.k.a. CTRL+Z as the EOF這個事實有關。正如Earlz指出的那樣,以二進制模式打開它可以修復這個問題,並且可以在Linux上運行。

3

你不能沒有操作系統的依賴做到這一點。 C語言規範說(7.19.3)

程序啓動時,三個文本流是預定義的......

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

+0

嗯,我希望能找到一個沒有任何操作系統特定代碼的解決方案。但它必須在Linux操作系統上運行,但我目前正在Windows上進行調試。那麼我應該如何在linux操作系統上解決這個問題呢? – user1745184

4

正如你已經注意到,你從stdin在ASCII模式下閱讀和它擊中SUB字符(替代品,又名CTRL +ž,又名DOS檔案結尾)。

你必須改變模式setmode同時爲二進制在Windows上:

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

/* ... */ 

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

Windows以外的平臺上,你就不會遇到這種區別的模式。

+0

我和OP有完全相同的問題。輸入文件有「**^Z **」,但是當我嘗試強制stdin讀取二進制文件時。它仍然到達eof。我試圖設置模式,但它不工作。可能想幫忙嗎?也許我會發佈一個新問題。 – eleijonmarck

+1

大家好, 想指出, _setmode(_fileno(stdin),_O_BINARY);必須位於main()函數的所有其他位置之前。 – eleijonmarck