C读取(来自stdin)停止在0x1a字符处
目前我正在为原始数据(如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 #include #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);
获得stdin
的fd
。
更多信息在这里 。
这个问题与windows将0x1a
也称为CTRL + Z视为EOF
这一事实有关。 正如Earlz指出的那样,以二进制模式打开它可以在Windows上修复它并在linux上运行。