【问题标题】:In c language. Why does it seem that system() is called prior to printf()? [duplicate]在c语言中。为什么似乎 system() 在 printf() 之前被调用? [复制]
【发布时间】:2021-04-13 14:32:07
【问题描述】:

请看代码。

#include "stdio.h"
#include "stdlib.h"

int main() {
    printf("Hello World");
    system("echo \"Hello c\"");
}

运行结果:

Hello c
Hello World

为什么似乎 system() 在 printf() 之前被调用?

以上测试结果是在manjaro系统上运行的,但是在windows系统上不存在这种现象?

【问题讨论】:

标签: c


【解决方案1】:

这是由于缓冲。在我看来,echo 在退出时会刷新其缓冲区。该输出进入 STDOUT。同时,您自己的代码在缓冲区中有 printf 输出,尚未刷新。

在 printf 行的末尾添加 \n 可以让您打印,因为 printf 默认情况下是行缓冲的。

有关更多信息,请在此处查看有关缓冲的 libc 部分 https://www.gnu.org/software/libc/manual/html_node/Stream-Buffering.html

【讨论】:

    【解决方案2】:

    因为

    • 您使用 printf 将某些内容放入输出缓冲区
    • 您执行带有输出的系统命令
    • 您隐式终止程序,该程序将输出缓冲区刷新到输出
    • 上面最后一个得到系统输出后的打印输出

    您只问了为什么,但如果您还想知道如何更改为您可能期望的内容,请使用 cmets 的建议:

    • Fred Larson:显式刷新
    • 尤金·肖。 : 在输出中用换行符隐式刷新

    【讨论】:

      【解决方案3】:

      您的输出行位于stdout 缓冲区中,因为您尚未在'\n' 中结束它。如果你用它来结束你的输出行,你会在调用系统之前打印该行。

      原因是如果输出设备是终端,stdio 使用行缓冲区。它缓冲所有字符,直到缓冲区已满(这很难看到,因为一个完整的缓冲区可以大到 16-32kb,它因系统而异)或输出一个新行。然后刷新缓冲区。但是你没有使用'\n',所以缓冲区在调用system(3)之后一直等到程序结束。

      你有几种方法可以解决这个问题:

      • 您可以通过调用fflush(stdout); 来强制刷新缓冲区。这将使stdio 按原样写入缓冲区,您将看到system() 命令的输出在您的行后面(没有新行)。
      • 您可以告诉stdio 不要在标准输出上使用缓冲区。这是通过setbuf(stdout, NULL); 完成的。这样,您创建的每个printf() 都将在格式化字符串时写入,因为没有缓冲区可以阻止它们。
      • 您可以在'\n' 中结束您的输出。只需在调用 system() 之前添加一个新行,您就会看到输出有多么不同。

      如果您的输出不是到 tty 设备,而是到文件,那么情况会更糟,因为只有当缓冲区完全填满(而不是行尾)时才会完成缓冲区刷新,您会看到在你的程序的所有输出之前你的system()调用的完整输出(假设你在调用printf()之前打印了几行,被调用的程序和这个程序的输出都被重定向到一个文件)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-19
        • 1970-01-01
        • 2015-02-08
        • 2011-09-04
        • 1970-01-01
        • 2014-01-08
        • 2012-08-01
        • 2015-12-27
        相关资源
        最近更新 更多