如何使用Bubble Sort/qsort()对结构体按车牌字母序排序?
解决车牌字符串排序仅按首字母生效的问题
咱们一步一步来排查两个版本的代码问题:
一、qsort版本的核心错误
你的compare函数犯了关键错误——直接用carroB->placa - carroA->placa是在比较两个字符串指针的内存地址差,根本不是按字符串的字符内容做字典序比较。这就是排序逻辑完全失效的根源。
正确的做法是用strcmp函数来对比两个车牌字符串,strcmp会逐字符进行字典序对比,返回值正好符合qsort对比较函数的要求:
int compare (const void * a, const void * b) { carro *carroA = (carro *)a; carro *carroB = (carro *)b; // 按车牌升序排序,strcmp返回值完全匹配qsort的规则 return strcmp(carroA->placa, carroB->placa); }
strcmp(a,b)的返回规则:
- 若a的字典序小于b,返回负数
- 若a和b完全相等,返回0
- 若a的字典序大于b,返回正数
这样修改后,qsort就能按完整车牌的字典序正确排序了。
二、冒泡排序版本的潜在问题
你的冒泡排序逻辑本身是正确的(用了strcmp对比车牌),但代码里有几个可能导致异常行为的细节问题:
- 使用不安全的
gets函数:gets不检查缓冲区大小,容易造成内存溢出,建议替换为更安全的fgets。 fflush(stdin)是未定义行为:C标准规定fflush仅适用于输出流,对输入流调用它的行为没有统一标准,不同编译器可能会出现输入读取异常,比如读空字符串,进而影响排序结果。- 部分字段未赋值:结构体里的
ano和valordiaria字段没有对应输入代码,输出时会显示垃圾值,但不影响排序逻辑。
修正后的冒泡排序输入部分示例:
for(x=0; x<3; x++) { printf("\nCarro: %d", (x+1)); printf("\nPlaca: "); // 用fgets读取输入,同时去掉末尾的换行符 fgets(car[x].placa, sizeof(car[x].placa), stdin); car[x].placa[strcspn(car[x].placa, "\n")] = '\0'; printf("Marca: "); fgets(car[x].marca, sizeof(car[x].marca), stdin); car[x].marca[strcspn(car[x].marca, "\n")] = '\0'; printf("Modelo: "); fgets(car[x].modelo, sizeof(car[x].modelo), stdin); car[x].modelo[strcspn(car[x].modelo, "\n")] = '\0'; printf("Ano: "); fgets(car[x].ano, sizeof(car[x].ano), stdin); car[x].ano[strcspn(car[x].ano, "\n")] = '\0'; printf("Valor da diaria: "); fgets(car[x].valordiaria, sizeof(car[x].valordiaria), stdin); car[x].valordiaria[strcspn(car[x].valordiaria, "\n")] = '\0'; }
三、验证修正后的效果
用你给出的测试输入:
Car 1 car plate: AGH-1234
car model: GTR
car brand: Nissan
car year: 2016
daily value of car: 100
Car 2 car plate: ABC-1234
car model: Corolla
car brand: Toyota
car year: 2014
daily value of car:50
无论是修正后的冒泡排序还是qsort版本,都会正确输出按车牌字典序排列的结果,ABC-1234会排在AGH-1234前面。
内容的提问来源于stack exchange,提问作者Pedrink
相关产品推荐
相关产品推荐

