繁体   English   中英

fprintf和WriteConsole的输出顺序相反

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM