C读取(来自stdin)停止在0x1a字符处

时间:2012-10-17 20:08:29

标签: c io stdin

目前我正在为原始数据(如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);

5 个答案:

答案 0 :(得分:4)

正如您所注意到的那样,您正在以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以外的平台上,您不会在模式中遇到这种区别。

答案 1 :(得分:3)

如果没有操作系统依赖关系,则无法执行此操作。 C语言规范说(7.19.3)

  

在程序启动时,预定义了三个文本流......

stdin是一个文本流。根据您的操作系统,可能有多种方法可以更改现有流的模式或访问低级流数据,但您声称不需要任何特定于操作系统的代码。

答案 2 :(得分:1)

您必须将文件作为二进制文件打开。

使用与

类似的内容
fopen("file", "rb");

答案 3 :(得分:1)

您可以使用_setmode将stdin转换为二进制模式。

还有freopen - 请参阅this SO question

答案 4 :(得分:0)

使用 read() 读取数据 由于您有兴趣从 stdin 获取数据,请使用

fd = fcntl(STDIN_FILENO, F_DUPFD, 0);

获取 fd stdin

更多信息here

这个问题与windows treats 0x1a a.k.a. CTRL+Z as the EOF的事实有关。正如Earlz指出的那样,以二进制模式打开它可以在Windows上修复它并在linux上运行。