使用 nanosleep 在 c 代码中利用小暂停的问题
problems utilitizing small pauses in c code using nanosleep
我是 C 初学者,正在尝试这个和那个。
我想逐个字母地显示一个字符串,中间有微小的停顿。所以我的想法是在显示每个字符后使用 sleep 或 usleep 暂停一下,但我读到在你自己的函数中使用 nanosleep 更有意义。所以我把我的小暂停放在函数“msleep”中以获得微秒暂停。
我输出了我的字符串 3 次。
一旦进入 main(),然后在函数 (fancyOutput) 中逐个 char 的 do-while-loop 中,最终在同一个函数中再次使用 printf 来检查它是否被正确处理。
我的问题:我预计,中间输出会一个字符一个字符地工作,并以 100/1000 秒的间隔分隔,但我遇到的是在 chowing 任何字符之前有一个很长的间隔,然后如果第二行和三。看起来编译器“意识到我打算做什么,并希望修改代码以提高效率”。所以我所有的停顿似乎都集中在一个长时间的休息中。
也许你还记得电视剧“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]=='[=10=]'));
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 是 显示,以便逐块显示信息(以优化显示速度)。
然后你需要添加一个 \n
到你的 printf 或添加一个 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]=='[=10=]'));
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-output 之后的解决方案。它按预期工作。
为有类似问题的人总结(猜测这也发生在 usleep 和类似的 self-made 函数中):
据我了解,printf 在 stdout 中“收集”数据,直到它“看到”\n,这表示一行结束。然后 printf“释放”标准输出。因此,在我最初的 post 中,它“保留”了 stdout 中的每个字符,在每个字符后暂停并最终在一个快速输出中释放了 stdout。
因此 fflush(stdout);
在每个字符输出后通过逐个字符清空标准输出字符。
希望对大家有帮助。
我是 C 初学者,正在尝试这个和那个。
我想逐个字母地显示一个字符串,中间有微小的停顿。所以我的想法是在显示每个字符后使用 sleep 或 usleep 暂停一下,但我读到在你自己的函数中使用 nanosleep 更有意义。所以我把我的小暂停放在函数“msleep”中以获得微秒暂停。
我输出了我的字符串 3 次。 一旦进入 main(),然后在函数 (fancyOutput) 中逐个 char 的 do-while-loop 中,最终在同一个函数中再次使用 printf 来检查它是否被正确处理。
我的问题:我预计,中间输出会一个字符一个字符地工作,并以 100/1000 秒的间隔分隔,但我遇到的是在 chowing 任何字符之前有一个很长的间隔,然后如果第二行和三。看起来编译器“意识到我打算做什么,并希望修改代码以提高效率”。所以我所有的停顿似乎都集中在一个长时间的休息中。
也许你还记得电视剧“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]=='[=10=]'));
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 是
然后你需要添加一个 \n
到你的 printf 或添加一个 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]=='[=10=]'));
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-output 之后的解决方案。它按预期工作。
为有类似问题的人总结(猜测这也发生在 usleep 和类似的 self-made 函数中): 据我了解,printf 在 stdout 中“收集”数据,直到它“看到”\n,这表示一行结束。然后 printf“释放”标准输出。因此,在我最初的 post 中,它“保留”了 stdout 中的每个字符,在每个字符后暂停并最终在一个快速输出中释放了 stdout。
因此 fflush(stdout);
在每个字符输出后通过逐个字符清空标准输出字符。
希望对大家有帮助。