如何使用GCC在C程序中的函数之间暂停?

时间:2013-06-23 05:44:43

标签: c gcc io stdout delay

所以我的问题是我的程序运行得太快,以至于我无法看到它的行为方式。它应该使文本沿终端的边缘爬行。我尝试使用sleep()printf(...)之间进行短暂停顿,以便我可以看到我们在打印时文本的位置。

这就是它的样子:

http://i.imgur.com/B6FFbNp.gif

所以我将sleep()函数放在printf之后,以便在再次开始循环之前暂停,并使文本移动缓慢。但是,它会在程序开始之前无限期地暂停程序。 usleepsystem("pause 1")也会发生这种情况。这就是它的样子:

http://i.imgur.com/krGW3lB.gif

=============================================== ===================================

编辑:

好的,我自己想出来了。似乎sleep()仅在我将\n放入字符串时才有效。我不知道为什么。我甚至没有在该死的手册中读过这篇文章。

所以,如果你有

printf("HELLO\n");
sleep(3);
printf("HELLO\n");
sleep(3);
printf("HELLO\n");

这将导致:

HELLO

[暂停3秒]

HELLO

[暂停3秒]

HELLO

但如果删除换行符,则会:

[暂停9秒] HELLO HELLO HELLO

我不知道为什么会这样,但它只是

=============================================== =================================== 编辑:

这就是我希望我的程序工作的方式: http://i.imgur.com/DXv7E60.gif

感谢您的回答

2 个答案:

答案 0 :(得分:5)

您的观察结果并非由于sleep()无法正常工作,而是printf()使用行缓冲的stdout这一事实。 “line buffered”意味着,已经写入stdout的内容被缓冲,直到达到该行的结尾,然后才刷新缓冲区的内容。

所以在第一个printf("HELLO");之后输出没有进入屏幕而是停留在缓冲区中,然后执行sleep(1);并让你等待。然后对于下一个printf("HELLO");输出仍然没有进入屏幕,但是下面的sleep(1);再次让你等待1秒......依此类推,直到你的程序打印到达一行结束一个'\n'或程序的结尾,它隐式地将输出缓冲区刷新到控制台。

您可以通过在stdout之后明确刷新printf()的输出缓冲区来避免此行为:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
  printf("HELLO");
  fflush(stdout);
  sleep(3);
  printf("HELLO");
  fflush(stdout);
  sleep(3);
  printf("HELLO");
/* fflush(stdout); */ /* not needed as buffers are implicitly flushed on the program's end */

  return 0;
}

答案 1 :(得分:1)

我通常做的快速黑客是制作一些缓冲区数组(例如char buf [10])并在迭代之间放置一个fgets(),这会强制程序等待来自用户的换行符。所以,例如,如果我们有:

.
.
.
for(i = 0; i < 1000000; ++i)
    printf("%d\n", i);
然后我们可以做

.
.
.
char buf[10];
for(i = 0; i < 1000000; ++i){
    printf("%d\n", i);
    fgets(buf, 10, stdin);
}

并使用回车键控制迭代。

我们也可以通过使用模数来停止每第n次迭代。使用上面的示例,我们现在将停止每100次迭代:

.
.
.
char buf[10];
for(i = 0; i < 1000000; ++i){
    printf("%d\n", i);
    if(i % 100 == 0)
        fgets(buf, 10, stdin);
}

更耗时但有效的方法是使用像GDB这样的专用调试器。