天花板编程手把手计划-第1期-第8天-打卡

题目

原问题链接
用你学过的C语言知识,设计一个番茄钟程序。要求满足如下功能:

可以设置倒计时时间
拥有倒计时效果
倒计时结束后有提醒
使用记录保存在文件中

解题思路

  • 计时效果
    因为程序计时部分运行时间几乎可以忽略,可以用Sleep()函数倒数计时;
  • 结束提醒
    引入媒体库播放声音
  • 保存文件
    freopen("record.txt", "a", stdout);

源码

#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <tchar.h>                    // 没这个库识别不出"_T"
#include <mmsystem.h>                // MCI库,媒体控制接口
#pragma comment(lib,"Winmm.lib")    //编译时自动链接 winmm 库.

int getTime(int &hours, int &minutes, int &seconds);
void record(int hours, int minutes, int seconds);
void timekeeper(int totalTimes);

void main()
{
    mciSendString(_T("open \"..\\music\\结束.wav\" alias musicTip "), NULL, 0, NULL);//加载结束的声音
    int hours, minutes, seconds;
    int totalTimes;
    totalTimes = getTime(hours, minutes, seconds);//获取倒计时
    timekeeper(totalTimes);//倒计时函数
    record(hours, minutes, seconds);//用文本记录结果
    system("pause");
}

int getTime(int &hours, int &minutes, int &seconds) //脑子短路用成了C++ 的引用
{
    int totalTimes;
    printf("按如下格式输入倒计时\n");
    printf("0:14:26\n");
    scanf("%d:%d:%d", &hours, &minutes, &seconds);
    while (hours > 24 || minutes >= 60 || seconds >= 60)//检查格式
    {
        printf("输入格式错误,请重新输入\n");
        scanf("%d:%d:%d", &hours, &minutes, &seconds);
    }
    printf("按下任意键开始计时\n");
    getch();
    totalTimes = hours * 60 * 60 + minutes * 60 + seconds;
    return totalTimes;
}

void record(int hours, int minutes, int seconds)
{
    freopen("record.txt", "a", stdout);//注意“a”表示追加文本。使用 “w” 就会清空文本重新写入
    printf("%02d:%02d:%02d\n", hours, minutes, seconds);
    fclose(stdout);
}

void timekeeper(int totalTimes)
{
    int hours, minutes, seconds;
    while (1)
    {
        system("cls");//清屏
        hours = totalTimes / 60 / 60;
        minutes = (totalTimes - hours * 60 * 60) / 60;
        seconds = totalTimes - hours * 60 * 60 - minutes * 60;
        printf("%02d:%02d:%02d\n", hours , minutes, seconds);//打印当前剩余时间
        Sleep(1000);//延时一秒
        totalTimes -= 1;
        if (totalTimes == 0)//计时结束
        {
            break;
        }
    }
    system("cls");
    printf("0:0:0\n");
    mciSendString(_T("play musicTip"), NULL, 0, NULL);//播放计时结束的声音
    printf("计时结束\n");
    Sleep(1000);
    mciSendString(_T("close musicTip"), NULL, 0, NULL);
}

执行结果

获取用户输入
动态的倒计时
结束会“滴”的一声
成功计时完毕才会记录结果

总结

遇到两个问题

freopen("record.txt", "a", stdout); 函数用完之后,就算进行了 fclose(stdout); 如果程序继续运行并试图在控制台输出字符,程序会中断。


int getTime(int &hours, int &minutes, int &seconds)
本来想用指针的,脑子一短路写错了,结果竟然没出错。
函数里 int &hours 这是定义了什么形参,还成功改变了实参的值。
查资料发现 int& 是对整型变量的引用
整型变量的引用定义,例如:
int a;
int &A=a;
引用即是一个变量的别名,例中A是a的一个别名,每一次访问A,对A的一系列操作实际上就是访问a,对a进行操作,此时的A和a在有些编译器中时同一个地址。在定义引用时必须初始化,且必须用有内存地址的对象初始化,初始化之后不可以在指向别的对象。
错误原因是我用了cpp的文件后缀,所以c++的语法是兼容的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,914评论 18 139
  • 上一篇中的课后练习大家普遍反映太简单了。其实,麻雀虽小,五脏俱全。今天我们来看看它的解法。 1. 题目 请编程实现...
    天花板阅读 1,527评论 2 17
  • 简介 C++98/03的设计目标:一、比C语言更适合系统编程(且与C语言兼容)。二、支持数据抽象。三、支持面向对象...
    认真学计算机阅读 5,345评论 0 53
  • 我们与他们 把生活中突如其来的事情都看做自己应该做的,看成为了我们的事业而忙碌。而非把工作看成他们的、别人该做的事...
    大橙子5996阅读 256评论 0 0
  • 第五章 平等大爱无偏私 天地不仁,以万物为刍狗;「圣人」不仁,以百姓为刍狗。天地之间,其犹橐钥乎。虚而不屈,动而愈...
    爱相续阅读 1,099评论 0 0