C语言车牌Binary Search失效问题:始终返回-1求排查解决
问题分析与修复方案
你的二分查找始终返回-1,主要是因为排序逻辑错误、输入处理错误和二分查找流程逻辑错误这几个核心问题,我帮你逐一拆解并修复:
1. 排序函数的致命错误
你的compare函数直接把整个carro结构体传给strcmp了,但strcmp是用来比较字符串的,不是结构体内存块!这会导致qsort排序的依据不是车牌,而是结构体在内存中的原始字节顺序,完全不符合按车牌排序的需求,二分查找自然找不到目标。
修复方法:明确比较结构体中的placa字段:
int compare (const void * a, const void * b) { carro *carroA = (carro *)a; carro *carroB = (carro *)b; // 只比较两个结构体的placa字段,而非整个结构体 return strcmp(carroA->placa, carroB->placa); }
2. 目标车牌输入的错误
你读入目标车牌的代码是scanf("%s", &k);,但k是字符数组名,本身就是指向首元素的指针,不需要加&——加了之后会传递数组的地址(类型是char (*)[10]),和scanf期望的char*不匹配,可能导致内存错误或读入异常。
修复:
scanf("%s", k);
3. 二分查找的流程逻辑错误
你的二分查找代码里,找到匹配项后没有终止循环,而是继续执行后面的printf("\n\n****Not found****\n\n\n"); return -1;,这就导致哪怕找到了目标,也会立刻输出"找不到"并返回-1,这是最致命的逻辑漏洞!
修复方法:找到匹配项后,输出信息并提前返回或跳出循环,只有当循环正常结束(确实没找到)时才输出Not found:
while(low<=high) { mid = (low+high)/2; int cmp_result = strcmp(k, car[mid].placa); // 把比较结果存起来,避免重复调用 if (cmp_result < 0) high=mid-1; else if (cmp_result > 0) low=mid+1; else { // 找到匹配项,输出信息后返回0(表示成功) printf("\nPlaca: %s", car[mid].placa); printf("\nMarca: %s", car[mid].marca); printf("\nModelo: %s", car[mid].modelo); printf("\nAno: %s", car[mid].ano); printf("\nValor da diaria: %s", car[mid].valordiaria); return 0; // 成功找到,结束程序 } } // 循环结束说明没找到目标 printf("\n\n****Not found****\n\n\n"); return -1;
完整修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_CARRO 5 typedef struct { char placa[50]; char marca[50]; char modelo[50]; char ano[50]; char valordiaria[50]; } carro; carro car[MAX_CARRO]; int compare (const void * a, const void * b) { carro *carroA = (carro *)a; carro *carroB = (carro *)b; return strcmp(carroA->placa, carroB->placa); } int main() { int x=0; // 车辆录入 for(x=0; x<MAX_CARRO; x++) { printf("\nCarro: %d", (x+1)); printf("\nPlaca: "); scanf("%s",car[x].placa); printf("Marca: "); scanf("%s",car[x].marca); printf("Modelo: "); scanf("%s",car[x].modelo); printf("Ano: "); scanf("%s",car[x].ano); printf("Valor da diaria: "); scanf("%s",car[x].valordiaria); } qsort (car, MAX_CARRO, sizeof(carro), compare); printf("\n\nSTRUCT ORDENADA: \n"); for(x=0; x<MAX_CARRO; x++) { printf("\n\n\nCarro: %d", (x+1)); printf("\nPlaca: %s", car[x].placa); printf("\nMarca: %s", car[x].marca); printf("\nModelo: %s", car[x].modelo); printf("\nAno: %s", car[x].ano); printf("\nValor da diaria: %s", car[x].valordiaria); } char k[50]; // 建议和placa长度统一,避免溢出 printf("\n\n\n*****BUSCA DE PLACAS*****\n\n\n\n"); printf("Digite a placa que deseja procurar: \n"); scanf("%s", k); int low, high, mid; low=0; high = MAX_CARRO-1; while(low<=high) { mid = (low+high)/2; int cmp_result = strcmp(k, car[mid].placa); if (cmp_result < 0) high=mid-1; else if (cmp_result > 0) low=mid+1; else { printf("\nPlaca: %s", car[mid].placa); printf("\nMarca: %s", car[mid].marca); printf("\nModelo: %s", car[mid].modelo); printf("\nAno: %s", car[mid].ano); printf("\nValor da diaria: %s", car[mid].valordiaria); return 0; } } printf("\n\n****Not found****\n\n\n"); return -1; }
额外小提示
- 注意车牌长度:我把
k的长度改成了50,和结构体里的placa一致,避免输入较长车牌时出现缓冲区溢出。 - 大小写问题:
strcmp区分大小写,如果输入的车牌大小写和录入的不一致会匹配失败,必要时可以统一转成小写/大写后再比较。
内容的提问来源于stack exchange,提问作者Pedrink
相关产品推荐
相关产品推荐

