C语言停车场系统中<time.h>库time_t相关代码错误求助
修正C语言停车场系统的代码错误
主要问题分析与修复步骤
1. 结构体定义错误
原结构体中直接给GirisSaati成员初始化={0}是C++语法,C语言不支持在结构体定义时初始化成员。另外,需要在结构体中添加time_t GirisSaati_t成员来存储转换后的时间戳,不能在函数内直接声明结构体成员。
修正后的结构体:
struct aracbilgiturleri { char Plaka[50]; // 车牌 char Model[50]; // 型号 int UretimYili; // 生产年份 char TankDurumu[50]; // 油量状态(有/无) char Renk[50]; // 颜色 struct tm GirisSaati; // 入场时间(tm结构体) time_t GirisSaati_t; // 转换后的时间戳,用于计算停放时长 } Arac[20]; // 最多存储20辆车信息
2. 时间输入的语法错误
原代码中scanf的地址参数错误,比如&Arac[i].GirisSaati.tm_year-1900,运算符优先级导致地址计算错误,且不能直接在地址中做数值修正。正确做法是先读取输入值,再手动修正后赋值给tm结构体成员:
tm_year需要是从1900年开始的偏移量,所以输入年份后要减1900tm_mon是0-11(对应1-12月),所以输入月份后要减1
修正后的时间输入代码片段:
int temp; // 输入年份 printf(" %d. Aracin Giris Yilini Giriniz => ",i+1); scanf("%d", &temp); Arac[i].GirisSaati.tm_year = temp - 1900; // 输入月份 printf(" %d. Aracin Giris Ayini Giriniz => ",i+1); scanf("%d", &temp); Arac[i].GirisSaati.tm_mon = temp - 1;
3. 时间戳转换的语法错误
原代码time_t Arac[i].GirisSaati_t = mktime(&Arac[i].GirisSaati);语法完全错误,因为GirisSaati_t是结构体成员,不能在函数内重新声明类型。正确写法是直接赋值给结构体成员,同时检查mktime的返回值(返回-1表示转换失败):
// 初始化tm结构体的其他成员,避免转换失败 Arac[i].GirisSaati.tm_wday = 0; Arac[i].GirisSaati.tm_yday = 0; Arac[i].GirisSaati.tm_isdst = -1; // 让系统自动判断夏令时 Arac[i].GirisSaati_t = mktime(&Arac[i].GirisSaati); if (Arac[i].GirisSaati_t == (time_t)-1) { printf("第%d辆车的时间转换失败,请检查输入的时间是否合法!\n", i+1); }
4. 输出格式错误
原代码中用%f输出tm_year、tm_mon等int类型成员,会导致格式混乱,应该用%d。另外,输出年份时加1900还原成实际年份,月份加1还原成1-12月:
printf(" %d. Aracin Giris Yili => %d \n",i+1, Arac[i].GirisSaati.tm_year + 1900); printf(" %d. Aracin Giris Ayini => %d \n",i+1, Arac[i].GirisSaati.tm_mon + 1); printf(" %d. Aracin Giris Gununu => %d \n",i+1, Arac[i].GirisSaati.tm_mday);
5. 其他优化点
- 移除未使用的
math.h头文件 - 添加输入合法性检查(比如车辆数量限制在1-20之间)
- 新增停放时长计算逻辑,用
difftime计算当前时间与入场时间的差值
完整修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> struct aracbilgiturleri { char Plaka[50]; // 车牌 char Model[50]; // 型号 int UretimYili; // 生产年份 char TankDurumu[50]; // 油量状态(有/无) char Renk[50]; // 颜色 struct tm GirisSaati; // 入场时间(tm结构体) time_t GirisSaati_t; // 转换后的时间戳,用于计算停放时长 } Arac[20]; // 最多存储20辆车信息 void AracEkle(int GirenSayisi); void Araclarilistele(int GirenSayisi); int main () { time_t su_an; // 当前时间 time(&su_an); printf("当前时间:%s", ctime(&su_an)); int GirenSayisi; printf("Giren Arac Sayisini Giriniz ==>"); // 输入入场车辆数量 scanf("%d", &GirenSayisi); // 检查输入合法性 if (GirenSayisi < 1 || GirenSayisi > 20) { printf("无效的数量,请输入1-20之间的数字!\n"); return 1; } AracEkle(GirenSayisi); Araclarilistele(GirenSayisi); return 0; } void AracEkle(int GirenSayisi) { int temp; for (int i = 0; i < GirenSayisi; i++) { printf(" %d. Aracin Plakasini Giriniz => ",i+1); // 输入车牌 scanf("%s", Arac[i].Plaka); printf(" %d. Aracin Modelini Giriniz => ",i+1); // 输入型号 scanf("%s", Arac[i].Model); printf(" %d. Aracin Uretim Yilini Giriniz => ",i+1); // 输入生产年份 scanf("%d", &Arac[i].UretimYili); printf(" %d. Aracin Tank Durumunu (Var/Yok) Giriniz => ",i+1); // 输入油量状态 scanf("%s", Arac[i].TankDurumu); printf(" %d. Aracin Rengini Giriniz => ",i+1); // 输入颜色 scanf("%s", Arac[i].Renk); // 输入入场年份 printf(" %d. Aracin Giris Yilini Giriniz => ",i+1); scanf("%d", &temp); Arac[i].GirisSaati.tm_year = temp - 1900; // 输入入场月份 printf(" %d. Aracin Giris Ayini Giriniz => ",i+1); scanf("%d", &temp); Arac[i].GirisSaati.tm_mon = temp - 1; // 输入入场日期 printf(" %d. Aracin Giris Gununu Giriniz => ",i+1); scanf("%d", &Arac[i].GirisSaati.tm_mday); // 输入入场小时 printf(" %d. Aracin Giris Saatini Giriniz => ",i+1); scanf("%d", &Arac[i].GirisSaati.tm_hour); // 输入入场分钟 printf(" %d. Aracin Giris Dakikasini Giriniz => ",i+1); scanf("%d", &Arac[i].GirisSaati.tm_min); // 输入入场秒数 printf(" %d. Aracin Giris Saniyesini Giriniz => ",i+1); scanf("%d", &Arac[i].GirisSaati.tm_sec); // 初始化tm结构体的其他成员(mktime需要,否则可能转换失败) Arac[i].GirisSaati.tm_wday = 0; Arac[i].GirisSaati.tm_yday = 0; Arac[i].GirisSaati.tm_isdst = -1; // 让系统自动判断夏令时 // 转换为时间戳 Arac[i].GirisSaati_t = mktime(&Arac[i].GirisSaati); if (Arac[i].GirisSaati_t == (time_t)-1) { printf("第%d辆车的时间转换失败,请检查输入的时间是否合法!\n", i+1); } } } // 列出所有车辆信息 void Araclarilistele (int GirenSayisi) { printf("****************************** ARACLAR ******************************\n"); // 车辆列表 for ( int i = 0; i < GirenSayisi; i++) { printf("%d. Aracin Plakasi => %s \n",i+1, Arac[i].Plaka); printf("%d. Aracin Modeli => %s \n",i+1, Arac[i].Model); printf("%d. Aracin Uretim Yili => %d \n",i+1, Arac[i].UretimYili); printf("%d. Aracin Tank Durumu => %s \n",i+1, Arac[i].TankDurumu); printf("%d. Aracin Rengi => %s \n",i+1, Arac[i].Renk); printf(" %d. Aracin Giris Yili => %d \n",i+1, Arac[i].GirisSaati.tm_year + 1900); printf(" %d. Aracin Giris Ayini => %d \n",i+1, Arac[i].GirisSaati.tm_mon + 1); printf(" %d. Aracin Giris Gununu => %d \n",i+1, Arac[i].GirisSaati.tm_mday); printf(" %d. Aracin Giris Saati => %d \n",i+1, Arac[i].GirisSaati.tm_hour); printf(" %d. Aracin Giris Dakikasi => %d \n",i+1, Arac[i].GirisSaati.tm_min); printf(" %d. Aracin Giris Saniyesi => %d \n",i+1, Arac[i].GirisSaati.tm_sec); if (Arac[i].GirisSaati_t != (time_t)-1) { printf(" %d. Aracin Giris Zaman Damgasi => %lld \n",i+1, (long long)Arac[i].GirisSaati_t); // 计算停放时长(当前时间 - 入场时间) time_t su_an; time(&su_an); long long sure = difftime(su_an, Arac[i].GirisSaati_t); printf(" %d. Aracin Park Edilen Sure => %lld saniye\n", i+1, sure); } printf("\n"); } }
补充说明
mktime函数会自动修正非法的时间值(比如13月会转为次年1月),但建议还是在输入时做合法性检查,避免错误输入。difftime函数用于计算两个时间戳的差值,返回秒数,方便计算停放时长。- 结构体中
tm_isdst设为-1,让系统自动判断是否为夏令时,提高时间转换的准确性。
内容的提问来源于stack exchange,提问作者Berat Zengin
相关产品推荐
相关产品推荐

