簡體   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