未终止EOL的重定向STDOUT放在缓冲区中,未显示

问题描述 投票:0回答:1

我正在编写一个程序(命令行前端),该程序重定向任意命令行程序的stdout和stdin。该问题与平台无关。为了理解问题,我编写了一个简单的命令行程序来解决问题:

#include <stdio.h>
main () {
  char Expression[200];
  printf ("Enter first expression: "); scanf ("%s", Expression);
  printf ("You have entered: %s\n", Expression);
  printf ("\n");
  printf ("(Now query with Stderr)\n");
  fprintf (stderr, "Enter second expression: "); scanf ("%s", Expression);
  printf ("You have entered: %s\n", Expression);
}

stdout“输入第一个表达式”位于输出缓冲区中,并且不会通过重定向的stdout管道发送到我的程序。因此,第一个问题是“输入第二个表达式”,因为缓冲区问题仅在stdout中发生,而不在stderr中发生。如果用户已键入输入并按RETURN,则发送缓冲区内容(第一个查询)。因此,stdout仅在EOL之后通过管道运行,stderr立即显示输出。

如果您运行Info-Zip UNZIP,并且正在解压缩已经存在的文件,则UNZIP将发送查询:

replace myfile.txt? [y]es, [n]o, [A]ll, [N]one, [r]ename:

并且此查询通过stderr发送,因此不会发生此问题。但是其他程序遇到了问题。

Windows 10的命令行前端已被重写。如果发生这种情况(例如,在覆盖现有文件时使用cmd.exe集成的“复制”命令),新的命令行前端将等待3秒(!),然后显示缓冲的查询。因此,看来Microsoft程序员需要编写“肮脏的hack”来解决此问题。

我的问题是:如果没有收到EOL,如何强制用户程序吐出stdout缓冲区?我具有在同一会话中由特殊帮助程序运行用户程序的会话的完全访问权限,该会话使我的图形前端程序与cmd.exe运行所在的文本窗口之间能够进行通信。

redirect command-line stdout stdin
1个回答
0
投票

我现在意识到必须在用户程序中放置“ fflush”命令。重定向时,Stdout始终会被缓冲,而Stderr不会。这就是stderr输出可以在stdout输出之前发生的原因。我编写了一个测试示例,其中stderr输出在显示前四行显示。

因此,所有正在编写stdout和stderr或编写用户查询的程序员都必须刷新stdout:

//first case: query and user input
char Expression[200];
printf ("Enter an expression: "); fflush (stdout); scanf ("%s", Expression);
printf ("You have entered: %s\n", Expression);

//second case: stderr output
fflush (stdout); fprintf (stderr, "An error has occured.");

我检查了Internet发布,并且似乎在所有平台上都出现了此问题。

因此,如果您使用stdout和stderr编写程序,请在这两种情况下使用fflush(stdout)。相反的情况(使用stderr然后使用stdout)没有问题,因为不会缓冲stderr。 (我希望我适用于所有平台。)

© www.soinside.com 2019 - 2024. All rights reserved.