在 win32 下的 stdin 上使用 fread() 时出现问题
我正在尝试在 Win32 下以二进制模式解析来自 stdin 的数据。 我的代码做的第一件事是在开头检查 4 字节标头:
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;
}
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);
}
此代码在 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
我做错了什么?
I'm trying to parse data from stdin in binary mode under Win32.
The first thing my code does is to check for a 4byte header at the beginning:
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;
}
stdin
has been switched to binary mode before reading from it:
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);
}
This code works fine under Linux, however on Win32 (specifically Windows XP), the fread
only seems to read a single byte and thus cause the evaluation to fail.
Example:
> 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
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 MSDN 文档,不允许为
freopen
的path
参数传递NULL
,因此对freopen
的调用几乎肯定会失败;你检查过返回值和errno
的值吗? C89 没有指定当path
为NULL
时freopen
的行为; C99 兼容,但 Microsoft C 运行时不(也不声称)兼容 C99。如果您确实需要从
stdin
读取二进制信息,您可能必须使用特定于平台的代码并直接使用ReadFile
文件GetStdHandle(STD_INPUT_HANDLE)
。According to the MSDN documentation, it's not permitted to pass
NULL
for thepath
parameter offreopen
, so the call tofreopen
is almost certainly failing; have you checked the return value and the value oferrno
? C89 does not specify the behavior offreopen
whenpath
isNULL
; C99 does, but the Microsoft C runtime is not (and does not claim to be) C99-compliant.If you really need to read binary info from
stdin
, you might have to use platform-specific code and read the raw binary data directly withReadFile
on the fileGetStdHandle(STD_INPUT_HANDLE)
.在 http://pubs.opengroup.org/onlinepubs/009695399/functions/freopen。 html 我发现了以下内容:
也许您应该检查您正在使用的编译器和库是否允许模式更改(从文本到二进制)。您使用哪个编译器?
更新/摘要
使用 MinGW,您可以调用 setmode() 来切换 stdin 流的模式。
您应该将模式设置为 _O_BINARY,该模式在 fcntl.h 中定义。
有关更多信息,请参见 http://gnuwin32.sourceforge.net/compile.html
At http://pubs.opengroup.org/onlinepubs/009695399/functions/freopen.html I have found the following:
Maybe you should check if the change of mode (from text to binary) is allowed by the compiler and libraries you are using. Which compiler are you using?
Update / summary
Using MinGW you can call setmode() to switch the mode of the stdin stream.
You should set the mode to _O_BINARY, which is defined in fcntl.h.
For more information see e.g. http://gnuwin32.sourceforge.net/compile.html