【问题标题】:printf not printing on consoleprintf 不在控制台上打印
【发布时间】:2012-10-13 15:48:10
【问题描述】:

我开始使用 C 语言。我使用 eclipse (juno) 作为我的 IDE 并安装了 CDT 插件。我还解压了 mingw64(GCC 编译器)。我写了一个非常简单的程序来看看它是否有效。这是我的代码:

#include <stdio.h>

int main()
{
    int age;
    printf("Hello, please enter your age:\n");
    scanf("%d", &age);
    printf("Your age is %d", age);
    return 0;
}

问题是输出缓冲区填充了第一个printf的字符串值,但没有输出到控制台。我必须输入一个数字,然后缓冲区才会将所有数据倒入控制台,所以我看到控制台是这样的:

1
Hello, please enter your age:
Your age is 1

而不是预期的:

Hello, please enter your age:
1
Your age is 1

现在,我发现我可以在第一个printf 之后使用fflush(stdout),但我认为这个解决方案并不优雅,甚至没有必要。关于如何克服这个问题的任何想法?

编辑 - 因为我在大学里学习这个,所以我不能使用课程中没有学到的任何东西,所以我可以使用@987654328 @和scanf

新编辑 - 我想我已经找到了对此的解释。正如我所说,我正在输出到 Eclipse 中的控制台视图。奇怪的是,如果我从 Windows 的命令行编译并运行程序,我会得到想要的结果。因此,我认为eclipse实际上是将输出写入文件并将其呈现在控制台窗口中。如何强制 eclipse 在我的运行配置中打开一个真正的命令行窗口?

【问题讨论】:

  • 旁注,fflush() 没有任何问题,它们非常方便
  • 这是非常奇怪的行为,\n 应该刷新stdout
  • 这不是重复的,因为我不能使用fflushfprintf 函数。当我从 Windows 中的命令行运行 gcc 时,我得到了正确的结果,所以我怀疑它是 eclipse 配置错误的情况。任何想法哪些配置?

标签: c eclipse gcc printf scanf


【解决方案1】:

输出被缓冲。

stdout 默认是行缓冲的,这意味着 '\n' 应该刷新缓冲区。为什么在你的情况下没有发生?我不知道。我需要有关您的应用程序/环境的更多信息。

但是,您可以使用 setvbuf() 控制缓冲:

setvbuf(stdout, NULL, _IOLBF, 0);

这将强制标准输出被行缓冲。

setvbuf(stdout, NULL, _IONBF, 0);

这将强制标准输出无缓冲,因此您不需要使用 fflush()。 请注意,如果您有大量打印,它将严重影响应用程序的性能。

【讨论】:

  • 我试过这个解决方案,发现你不能在调试模式下执行 printf。它卡住了,我得到了:*stopped,reason="end-stepping-range",frame=...
  • 这是我的解决方案。如果我直接在终端窗口中运行程序,我可以看到它的输出,但如果我尝试使用 tee 甚至将终端输出写入文件,我什么也得不到。
  • 你是对的。在我的例子中,输出被缓冲,并在程序结束后卸载,写入它在执行过程中积累的所有缓冲字符串,就在程序结束之后。
【解决方案2】:

显然这是 Eclipse 的一个已知错误。 WONT-FIX 解决了这个错误。我不知道为什么。链接在这里: Eclipse C Console Bug.

【讨论】:

  • 仍未解决。必须在您的代码中禁用或以其他方式处理缓冲。
【解决方案3】:

您可以尝试写入标准错误,而不是标准输出。

fprintf(stderr, "Hello, please enter your age\n");

您还应该查看this 相关线程。

【讨论】:

  • 我在我的大学学习这门 C 课程,因为是 101 门课程,所以我不能使用材料中没有的东西(我现在只能使用 printfscanf )。出于同样的原因,我不能使用 fflush。
  • 您是否正在输出到某种控制台?我在Linux上工作......所以我完全不熟悉Windows编译过程等。
  • 我所说的控制台是eclipse IDE中的控制台。 (控制台视图) - 但正如我在另一条评论中所说,当我通过命令行使用 gcc 编译时,我得到了想要的结果,所以我强烈怀疑这是一个 Eclipse 配置问题。有什么想法吗?
  • 有时如果编译器认为它正在输出到某种文件而不是控制台,它不会刷新缓冲区,直到它完全填满,即使在换行符上。也许这就是正在发生的事情,因为你通过 gcc 得到了你想要的。
  • 正确 - 那么是否可以强制 eclipse 在 windows 命令行而不是 eclipse 的控制台视图中运行 c 程序?
【解决方案4】:

在打印之前尝试设置:

setvbuf (stdout, NULL, _IONBF, 0);

【讨论】:

  • 是的 - 这会起作用,并在我发布在正确答案中的链接中提出。
【解决方案5】:

正如其他人所指出的,输出可以在控制台或 shell 有机会看到之前在您的程序中缓冲。

在包括 mac 在内的类 unix 系统上,stdout 默认具有基于行的缓冲。这意味着您的程序一看到换行符就会清空其stdout 缓冲区。

但是,在 Windows 上,换行符不再是特殊的,而是使用了完全缓冲。 Windows 根本不支持行缓冲;见the msdn page on setvbuf

所以在 Windows 上,一个好的方法是像这样完全关闭 stdout 缓冲:

setvbuf (stdout, NULL, _IONBF, 0);

【讨论】:

    【解决方案6】:

    c:\gygwin\bin 添加到PATH 环境变量作为系统环境变量或在您的eclipse 项目中(属性-> 运行/调试-> 编辑)

    【讨论】:

      【解决方案7】:
      1. 在您的项目文件夹中,创建一个“.gdbinit”文本文件。它将包含您的 gdb 调试器配置
      2. 编辑“.gdbinit”,并添加行(不带引号):“set new-console on”
      3. 构建项目后右键项目Debug>“Debug Configurations”,如下图

      4. 在“调试器”选项卡中,确保“GDB 命令文件”现在指向您的“.gdbinit”文件。否则,输入“.gdbinit”配置文件的路径:

      5. 单击“应用”和“调试”。应启动本机 DOS 命令行,如下所示

      【讨论】:

      • 有人测试过吗?