jba*_*ter 3 c windows pipe stdio
我试图在Win32下以二进制模式解析stdin中的数据.我的代码所做的第一件事就是在开头检查一个4byte的头:
int riff_header;
fread(&riff_header, sizeof(riff_header), 1, ifp);
// 'RIFF' = little-endian
if (riff_header != 0x46464952) {
fprintf(stderr, "wav2msu: Incorrect header: Invalid format or endianness\n");
fprintf(stderr, " Value was: 0x%x\n", riff_header);
return -1;
}
Run Code Online (Sandbox Code Playgroud)
stdin 在读取之前已经切换到二进制模式:
if (*argv[argc-1] == '-') {
fprintf(stderr, "Reading from stdin.\n");
infile = stdin;
// We need to switch stdin to binary mode, or else we run
// into problems under Windows
freopen(NULL, "rb", stdin);
}
Run Code Online (Sandbox Code Playgroud)
这段代码在Linux下工作正常,但是在Win32(特别是Windows XP)上,fread似乎只能读取单个字节,从而导致评估失败.例:
> ffmeg.exe -i ..\test.mp3 -f wav pipe:1 2> nul |..\foo.exe -o test.bin -
Reading from stdin.
foo: Incorrect header: Invalid format or endianness
Value was: 0x4
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
在http://pubs.opengroup.org/onlinepubs/009695399/functions/freopen.html,我发现了以下内容:
如果filename是空指针,则freopen()函数将尝试将流的模式更改为mode指定的模式,就好像当前与该流关联的文件的名称已被使用一样.在这种情况下,如果对freopen()的调用成功,则不需要关闭与流关联的文件描述符.它是实现定义的,允许更改模式(如果有),以及在什么情况下.
也许您应该检查您正在使用的编译器和库是否允许更改模式(从文本到二进制).你使用的是哪个编译器?
更新/摘要
使用MinGW,您可以调用setmode()来切换stdin流的模式.您应该将模式设置为_O_BINARY,它在fcntl.h中定义.有关更多信息,请参阅http://gnuwin32.sourceforge.net/compile.html
按照MSDN文档,它不允许通过NULL的path参数freopen,所以调用freopen几乎可以肯定是失败的; 你检查了返回值和值errno吗?C89没有规定的行为freopen时path是NULL; C99可以,但Microsoft C运行时不符合(并且声称不符合)C99.
如果您确实需要从中读取二进制信息stdin,则可能必须使用特定于平台的代码并直接ReadFile在文件上读取原始二进制数据GetStdHandle(STD_INPUT_HANDLE).
| 归档时间: |
|
| 查看次数: |
2815 次 |
| 最近记录: |