如何在C语言中基于结构体对象的字符串日期值实现从最新到最旧的排序
问题分析
首先看你这段代码的几个明显问题,直接导致排序完全不对:
arr数组完全没用到日期值:你声明了arr但从来没给它赋值,直接拿随机的垃圾值比较排序,这根本和你的日期半毛钱关系都没有啊!- 数组越界风险:第一个循环
for(i = 0; i <= njog; i++),如果njog是游戏的总数,那games的有效索引应该是0到njog-1,你访问games[njog]会越界,读取到未知内存的数据。 - 排序范围固定死了:你冒泡排序只循环了3次,只处理前4个元素,但如果你的游戏数量
njog不是4的话,剩下的元素根本没排序。 - 只排了日期字符串,没动原游戏数组:就算你把日期排对了,原
games数组里的游戏数据还是乱的,最后打印的只是排过的日期,不是对应游戏的信息(当然你现在只打印日期,但核心是要给游戏排序对吧?)
正确的实现思路
要解决日期排序,核心是把日期字符串转换成可直接比较的数值,比如把dd-mm-yyyy转成YYYYMMDD格式的整数(比如10-10-2022转成20221010),这样数值越大,日期越新,直接比较整数大小就可以排序。然后基于这个数值,对整个jogo结构体数组进行排序,而不是单独处理日期字符串。
完整代码实现
首先,先写一个辅助函数来转换日期:
// 将dd-mm-yyyy格式的日期字符串转为YYYYMMDD整数 long int data_para_numero(const char *data) { int dia, mes, ano; // 从字符串中解析出日、月、年 sscanf(data, "%d-%d-%d", &dia, &mes, &ano); // 组合成YYYYMMDD的整数 return (long int)ano * 10000 + mes * 100 + dia; }
然后修改你的排序函数,直接对games数组排序,同步交换整个结构体:
void ordenarjogos(jogo games[JOG], int njog) { int i, j; jogo temp; // 用来交换整个游戏结构体 long int data_atual, data_proxima; // 冒泡排序:从最新到最旧(降序) for (i = 0; i < njog - 1; i++) { for (j = 0; j < njog - 1 - i; j++) { // 转换当前和下一个游戏的日期为数值 data_atual = data_para_numero(games[j].data); data_proxima = data_para_numero(games[j+1].data); // 如果当前日期比下一个旧(数值更小),就交换位置,让新的在前 if (data_atual < data_proxima) { temp = games[j]; games[j] = games[j+1]; games[j+1] = temp; } } } // 测试打印排序后的日期 for (i = 0; i < njog; i++) { printf("%s\n", games[i].data); } }
测试验证
用你给出的输入日期:10-10-2011、10-10-2020、10-10-2022,转换后的数值分别是20111010、20201010、20221010。排序后会按从大到小排列,输出结果就是:
10-10-2022 10-10-2020 10-10-2011
完全符合你想要的“从最新到最旧”的需求。
额外提示
- 如果你的日期格式可能有变化(比如带前导零或者不同分隔符),可以在
sscanf里做适配,不过按你现在的输入格式,这个代码完全够用。 - 如果游戏数量很多,冒泡排序效率不高,可以换成
qsort(C标准库的快速排序),代码会更简洁,效率也更高,比如:
// 给qsort用的比较函数,降序排列 int comparar_jogos(const void *a, const void *b) { const jogo *jogo_a = (const jogo *)a; const jogo *jogo_b = (const jogo *)b; long int num_a = data_para_numero(jogo_a->data); long int num_b = data_para_numero(jogo_b->data); // 降序:如果num_a > num_b,返回-1,让qsort把a放在前面 return (num_a < num_b) - (num_a > num_b); } // 调用qsort的版本 void ordenarjogos_qsort(jogo games[JOG], int njog) { qsort(games, njog, sizeof(jogo), comparar_jogos); // 打印测试 for (int i = 0; i < njog; i++) { printf("%s\n", games[i].data); } }
这个版本对于大量数据来说比冒泡排序快很多,推荐使用。
内容的提问来源于stack exchange,提问作者Duochannel YT
相关产品推荐
相关产品推荐

