首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C语言时钟

C语言时钟
EN

Code Review用户
提问于 2021-09-19 18:17:37
回答 2查看 165关注 0票数 0

好的,下面是代码:如果有错误,请评论

代码语言:javascript
复制
#include <stdio.h>
#include <windows.h>

main()
{
    int h, m, s;
    int d = 1000;


    printf("Set the Clock time: \n");
    scanf("%d%d%d", &h,&m,&s);


    if (h > 24 || m > 60 || s > 60) {
        printf("ERROR!");
        exit(0);
    }
    while(1) {

        s++;
        if (s > 59) {
            m++;
            s = 0;
        }
        if (m > 59) {
            h++;
            m = 0;
        }
        if (h > 24) {
            h = 1;
        }
        printf("\n Clock: ");
        printf("%02d:%02d:%02d", h, m, s);
        Sleep(d);
        system("cls");
    }
}

所以,老实说,我不知道这段代码是否是好的和可读的:(这就是我在这里发布它的原因。

EN

回答 2

Code Review用户

发布于 2021-09-24 22:27:49

24小时可以吗?

而不是

代码语言:javascript
复制
if (h > 24 || m > 60 || s > 60),

我以为

代码语言:javascript
复制
if (h >= 24 || m >= 60 || s >= 60)

..。虽然允许24:00:00作为特例是可以的。

由于h,m,sint,因此需要对负值进行范围检查。

代码语言:javascript
复制
if (h >= 24 || h < 0 || m >= 60 || m < 0 ....

也许你想让闰秒像23:59:60那样成为宇宙时间?

使用现代C

代码语言:javascript
复制
// main()

int main()
// or 
int main(void)

验证用户输入

代码语言:javascript
复制
// scanf("%d%d%d", &h,&m,&s);
if (scanf("%d%d%d", &h,&m,&s) != 3) {
    printf("ERROR, not 3 integers\n");
    exit(0);
}

错误输出在带有'\n'

stderr上最佳

代码语言:javascript
复制
    //printf("ERROR!");
    //exit(0);
    fprintf(stderr, "ERROR!\n");
    return EXIT_FAILURE;

与数字

的一致性

而不是60和59,60,因为这是常识,如60秒/分钟,等等。

代码语言:javascript
复制
if (h >= 24 || m >= 60 || s >= 60) {
    ...
}
while(1) {
    s++;
    // if (m > 59) {
    if (s >= 60) {

避免赤裸裸的幻数

代码语言:javascript
复制
#define SEC_PER_MIN 60

if (... s >= SEC_PER_MIN) {
    ...
}
while(1) {
    s++;
    if (s >= SEC_PER_MIN) {

代码是..。可读(?)

  • 我觉得双线间距过大了。
  • 这是很重要的一课。不要手动格式化代码。人生苦短。使用带有自动格式化程序的IDE。

完成

刷新时,

printf("%02d:%02d:%02d", h, m, s);不一定输出,因为stdout通常是行缓冲的。

任一

代码语言:javascript
复制
printf("%02d:%02d:%02d", h, m, s);
fflush(stdout);
// or
printf("%02d:%02d:%02d\n", h, m, s);
票数 5
EN

Code Review用户

发布于 2021-09-19 20:37:35

不正确的输入验证

您的代码允许某人输入时间"24:60:60",您的程序将接受它。我还看到,时钟意味着显示时间从01:00到24:59:59,但它也会接受0作为时间。要确保只在显示的时间接受输入,请编写:

代码语言:javascript
复制
if (h < 1 || h > 24 || m >= 60 || s >= 60)
    ...

虽然24小时钟从00:00到23:59:59比较常见。

正确的错误报告

当您遇到错误时,正确的做法是将错误消息打印到stderr,然后使用非零退出代码(最好是EXIT_FAILURE )退出程序。

Sleep(1000)不完全睡眠1秒

Sleep()函数可能不会休眠您指定的确切时间,即使这样,打印时间和清除屏幕也需要一些时间。所以最有可能的是,你的时钟会慢一点。要使它正常工作,您需要检查实际时间,并在调用Sleep()之前确定您需要睡眠多少,直到一秒钟过去。了解当前时间的最可移植的方法是使用clock()函数。您的循环应该如下所示:

代码语言:javascript
复制
clock_t next_time = clock();

while (1) {
    /* Print clock */
    ...

    clock_t current_time = clock();
    next_time += CLOCKS_PER_SEC;
    clock_t difference = next_time - current_time;
    Sleep(difference * 1000 / CLOCKS_PER_SEC);
}

请注意,虽然clock()可能在实践中工作,但它也不能保证运行速度与“壁时”一样快。您可以使用的平台相关函数是GetSystemTime() for Windows,gettimeofday()clock_gettime()用于Linux和macOS。但原则是一样的。

避免不必要地调用system()

system()将导致创建一个新的shell进程,然后该shell将解析并执行您给出的命令。对于一些简单的操作(比如清除屏幕)来说,这是非常低效的,而且也不独立于平台(在大多数其他操作系统中,您必须使用"clear"而不是"cls"作为命令)。

有更有效的方法来清除屏幕,例如使用ANSI转义码,但还有一个更简单的选择:永远不要转到下一行,只需覆盖当前行即可。您可以通过在格式字符串中使用\r来做到这一点,该字符串将光标移回行的开头。我建议你写:

代码语言:javascript
复制
printf("\rClock: %02d:%02d:%02d", h, m, s);
fflush(stdout);

fflush()命令是必要的,以确保行立即写入屏幕,因为通常输出到stdout是行缓冲。

使其更加独立于平台的

不幸的是,在给定的时间内没有标准的C函数来睡眠。在Windows上,您必须使用Sleep(),在大多数其他操作系统上,您必须使用POSIX nanosleep()函数。有关使您的程序为多个操作系统编译的一些建议,请参见这个StackOverflow帖子

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/268159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档