求c语言源代码编写程序要求1输入年月份时分秒2输入增加的分钟数,输出输入的时间及增加分钟数后的时间

原问题:求c语言源代码编写程序要求1输入年月份时分秒2输入增加的分钟数,输出输入的时间及增加分钟数后的时间
分类:编程开发 > 最后更新时间:【2016-12-12 13:18:19】
问题补充:

求c语言源代码编写程序要求1输入年月份时分秒2输入增加的分钟数,输出输入的时间及增加分钟数后的时间求c语言源代码编写程序要求1输入年月份时分秒2输入增加的分钟数,输出输入的时间及增加分钟数后的时间。

最佳答案

根据题主的要求,我设计程序功能如下:

<1> 能够实现任意两个时间的加法(每月30天);

<2> 能够检测输入的时间信息是否符合规范;

<3> 能够将不符合规范的时间调整为规范的时间格式(支持正数、负数);

<4> 实现了菜单操作,并且输入错误有提示。

我在Windows 7下使用的编译器是MinGW-w64,下面是程序运行的截图:

下面是程序源代码:

#include <stdio.h>

// 用于表示测试时间是否合理的状态
#define YES (1)
#define NO (0)


// 用于判断用户输入
#define CREATE (1)
#define ADD (2)
#define QUIT (3)

// 声明并定义用于记录时间的结构体
typedef struct {
int year;
int month;
int day;
int hour;
int minute;
int second;
} tm;

// 用于从stdin接收用户输入的时间信息
// 形参是用于存储时间信息的数据结构的指针
// 返回值是同样是指向这个结构的指针
tm* create_tm(tm* buf);

// 将时间1(t1)和时间2(t2)求和,保存到时间1(t1)中
// 返回值为指向时间1(t1)的指针
// 题主要求只增加时间,但我实现了任意2个时间的加法
// 表示时间的数值是正数,也可以是负数
tm* add_tm(tm* t1, tm* t2);

// 用于测试输入的时间是否规范
// 形参是要进行测试的时间结构的指针
// 如果规范返回YES,否则返回NO
int is_tm_legal(tm* t);

// 用于将不规范的时间修改为规范的时间格式
// 形参是要进行“修复”的时间结构的指针
// 返回值指针同样指向形参的时间指针
tm* deal_tm(tm* t);

// 打印形参指定的时间格式
void print_tm(tm* t);

int main(void) {
int usr_choice; // 接收用户选择
tm t1; // 用于保存时间格式的数据结构
tm t2 = {0, 0, 0, 0, 0, 0}; // 用于保存时间格式的数据结构
int create_flag = NO;

do {
// 打印主菜单并获得用户输入
printf("Please input your choice. \n"
"\t<1> for create a TIME\n"
"\t<2> for Input minutes to ADD to the upper time.\n"
"\t<3> for quit.\nYour choice: ");
scanf("%d", &usr_choice);
getchar();

// 分析用户输入的数字
switch(usr_choice) {
case CREATE: // 选择创建基础时间信息
create_tm(&t1);
create_flag = YES; // 允许增加分钟
print_tm(&t1); // 显示时间
break;
case ADD: // 选择增加分钟
// 只有创建了基础时间才允许增加
if (YES == create_flag) {
// 打印并获得要增加的分钟
printf("Minutes to add: ");
scanf("%d", &(t2.minute));
add_tm(&t1, &t2); // 增加分钟
print_tm(&t1); // 显示时间
} else // 如果没有基础时间则报错
printf("Error: please input a time first.\n\n");
break;
case QUIT: // 选择退出并进行提示
printf("Bye!\n");
break;
default: // 输入其他数字,提示出错。
printf("Input error. Please retry.\n\n");
}
} while (QUIT != usr_choice);

return 0;
}

void print_tm(tm* t) {
if (t) {
printf("Time format ( YY-MM-DD hh:mm:ss ): %d-%d-%d"
" %d:%d:%d\n\n", t->year, t->month, t->day,
t->hour, t->minute, t->second);
} else {
printf("Error: the pointer is NULL.\n\n");
}
}

tm* create_tm(tm* buf) {
if (buf) {
// 录入时间
printf("\tYear: ");
scanf("%d", &(buf->year));
printf("\tMonth: ");
scanf("%d", &(buf->month));
printf("\tDay: ");
scanf("%d", &(buf->day));
printf("\tHour: ");
scanf("%d", &(buf->hour));
printf("\tMinute: ");
scanf("%d", &(buf->minute));
printf("\tSecond: ");
scanf("%d", &(buf->second));

// 检查时间格式是否规范
// 如果不规范,则修正时间格式
if (NO == is_tm_legal(buf)) {
deal_tm(buf);
}
}
return buf;
}

int is_tm_legal(tm* t) {
int ret = YES;
// 判断秒钟是否规范
if (t->second < 0 || t->second > 59)
ret = NO;
else {
// 判断分钟是否规范
if (t->minute < 0 || t->minute > 59)
ret = NO;
else {
// 判断小时是否规范
if (t->hour < 0 || t->hour > 24)
ret = NO;
else {
// 判断天是否规范
if (t->day < 1 || t->day > 30)
ret = NO;
else {
// 判断月是否规范
if (t->month < 1 || t->month > 12)
ret = NO;
}
}
}
}
return ret;
}

tm* deal_tm(tm* t) {
if (t) {
// 处理“秒钟”规范性问题
// 如果秒数不规范(second<0或者second>59),则需进位到分钟
t->minute += (t->second / 60);
t->second %= 60;
// 如果此时仍未负值,则表示为正数
if (t->second < 0)
t->second += 60;

// 处理“分钟”规范性问题
// 如果分钟不规范(minute<0或者minute>59),则需进位到小时
t->hour += (t->minute / 60);
t->minute %= 60;
// 如果此时仍未负值,则表示为正数
if (t->minute < 0)
t->minute += 60;

// 处理“小时”规范性问题
// 如果小时不规范(hour<0或者hour>24),则需进位到天
t->day += (t->hour / 24);
t->hour %= 24;
// 如果此时仍未负值,则表示为正数
if (t->hour < 0)
t->hour += 24;

// 处理“天”规范性问题
// 如果天数不规范(day<0或者day>30),则需进位到月
t->month += (t->day / 30);
t->day %= 30;
// 如果此时仍未负值,则表示为正数
if (t->day <= 0)
t->day += 30;

// 处理“月”规范性问题
// 如果月数不规范(month<0或者month>12),则需进位到年
t->year += (t->month / 12);
t->month %= 12;
// 如果此时仍未负值,则表示为正数
if (t->month <= 0)
t->month += 12;
}
return t;
}

tm* add_tm(tm* t1, tm* t2) {
if (t1 && t2) {
t1->second += t2->second;
t1->minute += t2->minute;
t1->hour += t2->hour;
t1->day += t2->day;
t1->month += t2->month;
t1->year += t2->year;
deal_tm(t1);
}
return t1;
}

追答:
请注意,我的代码经过测试,没有问题。但是有一部分注释因为使用复制/粘贴,之后局部修改的方法,因而导致了问题。具体出现在处理时间规范性的函数deal_tm( )中,请题主自行斟酌。 追答:
具体而言,注释错误出现在对日、月进位的描述上。这是因为对于时、分、秒而言,可以使用数字0。但是对于日、月而言,最小数值必须是1。
  • 追答:
    抱歉,题主。我发现自己代码中的一处问题,同样也是在deal_tm( )中,连同以上注释问题一并修改如下:tm* deal_tm(tm* t) { if (t) { // 处理“秒钟”规范性问题 // 如果秒数不规范(second<0或者second>59),则需进位到分钟 t->minute += (t->second / 60); t->second %= 60; // 如果此时仍未负值,则表示为正数 if (t->second minute hour year--; } } return t;}
    最佳答案由网友  grass_rt  提供
  • 公告: 为响应国家净网行动,部分内容已经删除,感谢网友理解。
    17

    分享到:

    其他回答

    其它网友回答:
    这个个人推荐用C标准库函数直接实现(否则计算较复杂),以下是参考:

    其它网友回答:
    #include <stdio.h>
    #include <time.h>
    int main()
    {
       struct tm tm_;
       const struct tm *tmp;
       int y, m, d, h, mm, s, ms;
       time_t t;
       printf("请输入年月日时分秒:\n"); //(用-号分隔)
       scanf("%d-%d-%d-%d-%d-%d", &y, &m, &d, &h, &mm, &s);
       tm_.tm_year  = y - 1900; //年
       tm_.tm_mon   = m - 1; //月,0开始
       tm_.tm_mday  = d; //日
       tm_.tm_hour  = h; //时
       tm_.tm_min   = mm; //分
       tm_.tm_sec   = s; //秒
       tm_.tm_isdst = 0;  //夏令时
       t = mktime(&tm_); //生成时间
       printf("请输入分钟数:\n"); ;
       scanf("%d", &ms);
       ms *= 60; //化为秒
       t += ms;
       tmp = localtime(&t); //转换格式
       printf("%d %d %d %d %d %d\n", y, m, d, h, mm, s);
       printf("%d %d %d %d %d %d\n", tmp->tm_year+1900, tmp->tm_mon + 1, tmp->tm_mday , tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
       return 0;
    }

      推荐