C语言任务管理程序写入日期字段后读取输出乱码问题
任务管理程序日期字段乱码修复
问题表现
新增任务功能写入日期后,查看任务时日期字段输出无意义整型数值,例如输入起止日期均为11/11/1111时,对应输出为6421994、6422005,所有日期输入均触发同类异常。
问题根因
代码存在4处直接触发异常的逻辑错误:
- 读取到的日期值未存入结构体:case '1'中通过
scanf读取的日、月、年值仅存放在临时整型变量dd/mm/yyyy中,从未格式化写入结构体t的Begin_date、End_date字符数组成员,写入文件的这两个字段是未初始化的栈内存垃圾值。 - 输出格式符与字段类型不匹配:case '2'打印任务时,对字符数组类型的日期字段使用
%d整型格式符,实际将数组首内存地址解析为整数输出,和字段存储的内容完全无关。 - 日期变量被覆盖:读取结束日期时复用了同一组
dd/mm/yyyy变量,直接覆盖了刚读取到的开始日期值,即使后续做格式化也无法获取正确的开始日期。 - 文件名拼写错误:case '4'删除任务后重新打开文件时,将
task.txt错写为taxt.txt,会导致文件打开失败,后续操作直接崩溃。
修复代码
1. 修正新增任务分支(case '1')逻辑
读取日期后单独格式化存入结构体对应字段,同时去掉scanf多余的取地址符:
case '1': system("cls"); fseek(fp,0,SEEK_END); another = 'y'; while(another == 'y') { printf("\nEnter Task_Name: "); scanf("%s", t.Task_Name); printf("\nEnter Leader: "); scanf("%s", t.Leader); printf("\nEnter L_Email: "); scanf("%s", t.L_Email); printf("\nEnter Member: "); scanf("%s", t.Member); printf("\nEnter Mem_Email: "); scanf("%s", t.Mem_Email); // 读取并写入开始日期 int s_dd, s_mm, s_yyyy; printf("\nEnter Begin_date(dd/mm/yyyy): "); scanf("%d/%d/%d", &s_dd,&s_mm,&s_yyyy); sprintf(t.Begin_date, "%02d/%02d/%04d", s_dd, s_mm, s_yyyy); // 读取并写入结束日期 int e_dd, e_mm, e_yyyy; printf("\nEnter End_date(dd/mm/yyyy): "); scanf("%d/%d/%d", &e_dd,&e_mm,&e_yyyy); sprintf(t.End_date, "%02d/%02d/%04d", e_dd, e_mm, e_yyyy); fwrite(&t,recsize,1,fp); printf("\nAdd another task(y/n) "); fflush(stdin); another = getche(); } break;
2. 修正查看任务分支(case '2')输出格式
将日期字段的输出格式符从%d改为匹配字符串类型的%s:
case '2': system("cls"); rewind(fp); printf("Task Name|Leader|Leader Email|Member|Member Email|Begin Date|End Date"); while(fread(&t,recsize,1,fp)==1) { printf("\n%s %s %s %s %s %s %s",t.Task_Name,t.Leader,t.L_Email,t.Member,t.Mem_Email,t.Begin_date,t.End_date); } getch(); break;
3. 修正更新任务分支(case '3')日期写入逻辑
读取新的结束日期后,补全格式化写入结构体的代码:
printf("Enter new End Date(dd/mm/yyyy): "); scanf("%d/%d/%d",&dd,&mm,&yyyy); sprintf(t.End_date, "%02d/%02d/%04d", dd, mm, yyyy); // 新增该行 fseek(fp,-recsize,SEEK_CUR); fwrite(&t,recsize,1,fp);
4. 修正删除分支(case '4')文件名拼写错误
// 原代码错写为taxt.txt,修正为正确文件名 fp = fopen("task.txt", "rb+");
注:
fflush(stdin)是标准C未定义的行为,仅在部分DOS/Windows编译器下可用,若需跨编译器兼容可自行替换为清空输入缓冲区的标准实现。
内容的提问来源于stack exchange,提问作者user19375357
相关产品推荐
相关产品推荐

