我是一个C初学者,正在尝试这个和那个。
我想一个字母一个字母地显示字符串,中间有微小的停顿。所以我的想法是在显示每个字符后使用sleep或usleep进行短暂的暂停,但我读到在自己的功能中使用nanosleep更有意义。所以我把我的小停顿放在一个函数";msleep";以获得微秒级的暂停。
我输出字符串3次。在main((中一次,然后在函数(fancyOutput(的do-while循环中一个字符接一个字符,最后在同一个函数中用printf再次检查它是否被正确处理。
我的问题是:我原以为中间的输出会一个字符接一个字符地工作,并以100/1000秒的间隔进行分隔,但我所经历的是在咀嚼任何字符之前的长时间休息,然后在第二行和第三行快速输出。它看起来像编译器";意识到我计划做什么,并希望修改代码以提高效率"因此,我所有的停顿似乎都集中在一次长时间的休息中。
也许你还记得电视剧中的字幕;x文件"-我想制作的那种东西。
当然,有更好、更复杂的方法来记录我将要尝试的内容,但我想学习和了解正在发生的事情。有人能帮我吗?
我在基于debian的带有gcc的发行版上使用代码时钟。
#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]==' '));
printf("n");
printf("%sn", 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("%sn", 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正在缓冲显示,以便逐块显示信息(以优化显示速度(。
然后,您需要向printf添加n
,或者添加stdout的刷新。
另一个解决方案是使用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]==' '));
printf("n");
printf("%sn", 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("%sn", 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和类似的自制函数也会发生这种情况(:据我所知;收集";数据在stdout中,直到它";看到";\n、 其指示一条线的结束。然后打印f";释放";stdout。所以在我最初的帖子中;保持";stdout中的每个字符,在每个字符后暂停,最后在一个快速输出中发布stdout。
因此fflush(stdout);
在每个通过输出的字符之后逐个清空stdout字符。
希望它能帮助别人。