2012-10-17 69 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