[英]Output of fprintf and WriteConsole happen in reverse order
我在Windows中看到控制台I / O的奇怪行为。 当我使用CONOUT$
作为路径打开FILE *
,应该打开控制台的stdout
。 如果我将该指针用于fprintf
,然后用于WriteConsole
,则您会认为消息会以各自的顺序出现,但实际上却是相反的。
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <io.h>
int main(int argc, char *argv[]) {
FILE *fout = fopen("CONOUT$", "w");
fprintf(fout, "Hello world!\n");
LPSTR goodbye = "Goodbye, cruel world!\n";
DWORD length = strlen(goodbye);
DWORD written;
WriteConsole(_get_osfhandle(_fileno(fout)), goodbye, length, &written, NULL);
return 0;
}
并输出:
Goodbye, cruel world!
Hello world!
为什么是这样? 我的猜测与Win32 I / O功能和stdio
同步(或者说不同步)有关。 我知道C ++ iostream
需要特别注意才能与stdio
同步,所以也许Win32不会这样做?
这可能与stdio.h
添加到输出中的某些缓冲有关。 尝试添加一个
fflush(fout);
在fprintf
。 或者,您可以尝试
setbuf(fout, null);
为输出流禁用缓冲。
至于“奖金”( printf
正常工作):Afaik stout
通常以一种方式设置,即在每个换行符之后自动刷新。
尽管理论上不应完全缓冲fout
,但几乎可以肯定它与stdio
缓冲有关。
C11§7.21.5.3/ 8:“当打开且仅当可以确定不引用交互式设备时,该流才被完全缓冲。该流的错误和文件结束指示符被清除。” 因此,Windows stdio实现可能无法确定CONOUT$
是交互式设备,但是标准的措辞似乎是,如果有疑问,则不应完全缓冲打开流。 它可能是行缓冲打开的,但是在fprintf
输出\\n
,所以在这种情况下应该没问题,实际上,使用printf
可以证明这一点。
您可以尝试使用setvbuf
关闭fout
缓冲,看看是否有帮助。
绝对是对stdio的阻碍。 我在MSVC2012和mingw-w64实现中都收到了相同的输出。
我决定从stdio层切换到POSIX层,输出为:
Hello world!
Goodbye, cruel world!
您的代码,稍作修改:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <io.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
int fout = _open("CONOUT$", _O_WRONLY);
char *hello = "Hello world!\n";
_write(fout, hello, strlen (hello));
LPSTR goodbye = "Goodbye, cruel world!\n";
DWORD length = strlen(goodbye);
DWORD written;
WriteConsole(_get_osfhandle(fout), goodbye, length, &written, NULL);
_close(fout);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.