Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用C语言制作分秒计时器_C - Fatal编程技术网

如何用C语言制作分秒计时器

如何用C语言制作分秒计时器,c,C,我正在努力用c语言制作一个计时分秒的计时器。我试图通过将时间打印到控制台来测试它,但它似乎没有显示任何内容。我的代码中有什么错误吗 #include <stdio.h> #include <stdlib.h> #include <windows.h> #define TRUE 1 int main( void ) { int min = 0; int sec = 0; while (TRUE) { sec

我正在努力用c语言制作一个计时分秒的计时器。我试图通过将时间打印到控制台来测试它,但它似乎没有显示任何内容。我的代码中有什么错误吗

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define TRUE 1

int main( void )
{

    int min = 0;
    int sec = 0;

    while (TRUE)
    {
        sec++;
        Sleep(1000);
        printf("%2d:%2d", min, sec);
        if (sec == 59)
        {
            min++;
            sec = 0;
        }
    }
    return 0;
}
#包括
#包括
#包括
#定义真1
内部主(空)
{
int min=0;
整数秒=0;
while(TRUE)
{
sec++;
睡眠(1000);
printf(“%2d:%2d”,分钟,秒);
如果(秒=59)
{
min++;
秒=0;
}
}
返回0;
}

出于性能原因,
printf
被缓冲。也就是说,在缓冲区已满之前,它不会显示。首先尝试在结尾添加一个新行字符:

    printf("%2d:%2d\n", min, sec);
如果不起作用,可以通过调用
fflush(stdout)强制输出缓冲区刷新

我的代码中有什么错误吗

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define TRUE 1

int main( void )
{

    int min = 0;
    int sec = 0;

    while (TRUE)
    {
        sec++;
        Sleep(1000);
        printf("%2d:%2d", min, sec);
        if (sec == 59)
        {
            min++;
            sec = 0;
        }
    }
    return 0;
}
有几件事看起来不对劲。第一个是
stdout
行缓冲-请参阅eduffy的答案

第二个问题是你正在做
sec++;睡眠(1000)
,这意味着
将每1000秒或更长时间递增一次

第三个问题是
if(sec==59;
是错误的,需要
if(sec==60)
。否则每分钟有59秒

第四个问题是
sleep(1)
将至少休眠1秒,但可能会休眠2秒、10秒或1234秒。要防止出现这种情况,您需要类似以下内容:

expiry = now() + delay;
while(true) {
    sleep(expiry - now() ):
    expiry += delay;
 }
其基本思想是,如果一次睡眠时间过长,那么下一次睡眠的睡眠时间就会减少;而这最终将是“平均正确的”


最后一个问题是
sleep()
没有足够的精度。对于1秒的延迟,您希望能够睡眠几分之一秒(例如,可能是9/10秒)。根据针对哪个操作系统的编译器,您可能可以使用更好的编译器(例如,可能是
nanosleep()
).不幸的是,可能没有什么是真正好的(例如,某种“
nanosleep\u直到(到期时间)
”可以防止IRQ和/或任务切换引起的抖动,这些抖动发生在您确定
现在
之后,但在您调用类似“
nanosleep()
”的东西之前).

我只会检查系统时间,而不是记录秒/分钟。这是因为,您的睡眠时间可能不精确到1000毫秒,因此随着时间的推移,您的计数器将不准确

由于您使用的是Windows,下面是对您的代码稍加修改的版本:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>

int main()
{
    for (;;)
    {
        time_t now = time(NULL);
        struct tm* ptm = localtime(&now);
        printf("%02d:%02d\n", ptm->tm_min, ptm->tm_sec);
        Sleep(1000);
    }

    return 0;
}
#包括
#包括
#包括
#包括
int main()
{
对于(;;)
{
time\u t now=时间(空);
struct tm*ptm=localtime(&now);
printf(“%02d:%02d\n”,ptm->tm_min,ptm->tm_sec);
睡眠(1000);
}
返回0;
}

我希望这能有所帮助。

正如您所问,您的代码中有几处错误,我会在阅读时告诉您。请参见下文

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

#define TRUE 1

int main( void )
{

    int min = 0;
    int sec = 0;

    while (TRUE)
    {
        sec++;
        Sleep(1000);
  • 这已经在其他答案中说明过了,但让我解释一下它是如何工作的,这样您就可以理解缓冲是如何工作的。缓冲区是一大块内存(通常是512字节),由
    printf()
    填充,因此它只调用
    write()
    当它填满了一个完整的数据缓冲区时。这允许stdio保存系统调用以进行实际写入,因此在传输大量数据时效率更高

    在交互式应用程序上,这是不适用的,因为如果在任何输入完成之前不强制缓冲区执行
    fflush()
    ,则不会执行任何输出,因此当输出是tty设备时(stdio可以从与标准输出相关联的文件描述符中知道)然后它切换到行模式缓冲,这意味着
    printf()
    将在以下情况下清除缓冲区:1)缓冲区已满,或2)在输出中找到换行符
    \n
    时。因此,解决问题的一种方法是在字符串末尾添加一个
    \n
    ,或者调用
    fflush(stdout)printf()
    后的code>

  • 当您在比较前增加秒数时,您必须检查
    60
    而不是
    59
    ,当您在增加秒数后与
    60
    进行比较时,将其转换为
    0
  • 当分钟数达到
    60
    时,你也应该对分钟数做同样的处理。由于您没有包含此代码,我假设您没有考虑小时计时

  • 对于我的意思,完整的解决方案可以是:

    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <windows.h>
    
    int main()
    {
        long start_timestamp;
        long display_timestamp;
    
        start_timestamp = time(NULL);
    
        for(;;) { /* this is the same as while(TRUE) */
                display_timestamp = time(NULL);
                int elapsed = display_timestamp - start_timestamp;
                int min = elapsed / 60;
                int sec = elapsed % 60;
                /* the \r in next printf will make to print a single carry
                 * return in the same line, so the time updates on top of
                 * itself */
                printf("\r%02d:%02d", min, sec); fflush(stdout);
                Sleep(100); /* as you print the time elapsed, you don't
                             * mind if you shorten the time between 
                             * displays. */
        }
    }
    
    #包括
    #包括
    #包括
    #包括
    int main()
    {
    长启动时间戳;
    长显示时间戳;
    开始时间戳=时间(空);
    对于(;;){/*这与while(TRUE)相同*/
    显示时间戳=时间(空);
    int PERASED=显示时间戳-开始时间戳;
    int min=经过的时间/60;
    整数秒=经过的%60;
    /*下一个printf中的\r将使打印单个进位
    *返回在同一行中,因此时间更新在
    *本身*/
    printf(“\r%02d:%02d”,分钟,秒);fflush(标准输出);
    睡眠(100);/*当您打印经过的时间时,您不会
    *介意你缩短两人之间的时间吗
    *显示*/
    }
    }
    
    它的bufferedIt将要显示的内容保留在内存中,直到它准备好显示为止,这是什么意思。写入显示器的成本很高,因此I/O例程尽量做到智能化,等待最佳时间写入输出。通常,当你开始一个换行是一个好时机,必须有数百个重复的职位,所以相关的行缓冲,但我似乎找不到一个好的。有可能很多问题都有不恰当的标题,就像这个问题一样。这里的问题是你的程序没有显示任何输出,但标题是“如何制作分秒计时器”。这不是
                {
                    min++;
    
                    sec = 0;
                }
            }
            return 0;
        }
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    #include <windows.h>
    
    int main()
    {
        long start_timestamp;
        long display_timestamp;
    
        start_timestamp = time(NULL);
    
        for(;;) { /* this is the same as while(TRUE) */
                display_timestamp = time(NULL);
                int elapsed = display_timestamp - start_timestamp;
                int min = elapsed / 60;
                int sec = elapsed % 60;
                /* the \r in next printf will make to print a single carry
                 * return in the same line, so the time updates on top of
                 * itself */
                printf("\r%02d:%02d", min, sec); fflush(stdout);
                Sleep(100); /* as you print the time elapsed, you don't
                             * mind if you shorten the time between 
                             * displays. */
        }
    }