2

目前我正在为原始数据(如 jpg 等)实施 Burrows-Wheeler 变换(和逆变换)。在对文本文件等普通数据进行测试时,不会出现任何问题。但是在读取 jpg 文件时,例如它会在字符 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);
4

5 回答 5

5

正如您所注意到的,您正在以 ASCII 模式读取数据,stdin并且它遇到了 SUB 字符(替换,又名CTRL+ Z,又名 DOS End-of-File)。

setmode您必须在 Windows 上使用 while 将模式更改为二进制:

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

/* ... */

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

在 Windows 以外的平台上,您不会在模式上遇到这种区别。

于 2012-10-17T20:26:10.823 回答
3

如果没有操作系统依赖性,您将无法做到这一点。C 语言规范说 (7.19.3)

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

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

于 2012-10-17T20:25:55.277 回答
2

您可以使用_setmode将标准输入转换为二进制模式。

还有freopen- 看到这个 SO question

于 2012-10-17T20:25:07.813 回答
1

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

fd = fcntl(STDIN_FILENO, F_DUPFD, 0);

获得fdstdin

更多信息在这里

这个问题与Windows 将0x1aakaCTRL+Z视为EOF. 正如 Earlz 指出的那样,以二进制模式打开它可以在 Windows 上修复此问题,并且也可以在 linux 上运行。

于 2012-10-17T20:16:46.460 回答
1

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

使用类似于

fopen("file", "rb");
于 2012-10-17T20:10:08.537 回答