问题描述
我是C初学者,正在尝试这种方式。
我想逐个字母地显示一个字符串,并且之间有微小的停顿。所以我的想法是在显示每个字符后使用睡眠或usleep稍作停顿,但我读到在自己的函数中使用nanosleep更有意义。因此,我将小暂停时间放在函数“ msleep”中以获取微秒的暂停时间。
我的字符串输出了3次。 一次进入main(),然后在一个函数(fancyOutput)中按字符进行一次do-while循环,最后在与printf相同的函数中再次进行检查,以检查是否处理正确。
我的问题:我希望中间输出可以逐个字符地工作,并以100/1000秒的间隔分开,但是我遇到的情况是在中断任何char之前需要很长的休息,然后在第二和第三行进行快速输出。看起来编译器“实现了我打算做的事情,并希望修改代码以提高效率”。所以我所有的停顿似乎都花了很长的时间。
也许您想起了电视连续剧“ x文件”中的标题-我想制作类似的东西。
可以肯定,有更好,更复杂的方法来归档我要尝试的内容,但是我想学习并了解正在发生的事情。有人可以帮我吗?
我正在使用基于gcc的基于Debian的发行版上的代码时钟。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int msleep(long tms);
void fancyOutput(char inputToOutput[]);
int msleep(long tms)
{
struct timespec ts;
int ret;
if (tms < 0)
{
return -1;
}
ts.tv_sec = tms / 1000;
ts.tv_nsec = (tms % 1000) * 1000000;
do
{
// printf("sleeping for %d",ret);
ret = nanosleep(&ts,&ts);
}
while (ret);
return ret;
}
void fancyOutput(char inputToOutput[])
{
int counter = 0;
do
{
printf("%c",inputToOutput[counter]);
msleep(100);
++counter;
}
while (!(inputToOutput[counter]=='\0'));
printf("\n");
printf("%s\n",inputToOutput); // only check,if string was properly handled over to function
}
char output[] = "This string shall appear char by char in the console.";
void main(void)
{
printf("%s\n",output); // only check,if string was properly set and initialized
fancyOutput(output); // here the function above is called to output the string char by cchar with tiny pauses between
}
解决方法
您遇到缓冲区问题。
当您在没有\n
(换行)的情况下使用printf时,C为buffering,以便逐块显示信息(以优化显示速度)。
然后,您需要向打印文件中添加\n
或添加标准输出的刷新。
另一种解决方案是使用stderr,它没有缓冲区,但是stderr的意思是不输出错误:)
您也可以选中setvbuf来更改缓冲。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int msleep(long tms);
void fancyOutput(char inputToOutput[]);
int msleep(long tms)
{
struct timespec ts;
int ret;
if (tms < 0)
{
return -1;
}
ts.tv_sec = tms / 1000;
ts.tv_nsec = (tms % 1000) * 1000000;
do
{
// printf("sleeping for %d",ret);
ret = nanosleep(&ts,&ts);
}
while (ret);
return ret;
}
void fancyOutput(char inputToOutput[])
{
int counter = 0;
do
{
printf("%c",inputToOutput[counter]);
flush(stdout);
msleep(100);
++counter;
}
while (!(inputToOutput[counter]=='\0'));
printf("\n");
printf("%s\n",inputToOutput); // only check,if string was properly handled over to function
}
char output[] = "This string shall appear char by char in the console.";
void main(void)
{
printf("%s\n",output); // only check,if string was properly set and initialized
fancyOutput(output); // here the function above is called to output the string char by cchar with tiny pauses between
}
,
因此,我尝试了将fflush(stdout);
放置在循环中char输出之后的解决方案。它按预期工作。
总结那些有类似问题的人(猜想这也发生在usleep和类似的自制函数中): 正如我了解的那样,printf在stdout中“收集”数据,直到它“看到” \ n,这表示行的末尾。然后,printf“释放”标准输出。因此,在我的第一篇文章中,它“保留”了stdout中的每个字符,在每个字符之后暂停了一下,最后以一个快速输出释放了stdout。
因此,fflush(stdout);
在每个字符通过空的stdout字符逐个字符输出之后。
希望它可以帮助其他人。