C 語言中字符串**不能**用 == 或 != 比較,必須使用 strcmp。本文詳細說明 strcmp 返回值含義、正確判斷邏輯,並分析 USACO 「貪婪送禮」題目中的比較錯誤。
#include
int strcmp(const char *str1, const char *str2);
| 返回值 | 含義 | 邏輯判斷 |
|---|---|---|
0 | str1 == str2 (內容相等) | if (strcmp(a,b) == 0) 相等 |
> 0 | str1 > str2 (字典序) | if (strcmp(a,b) > 0) a 大於 b |
< 0 | str1 < str2 (字典序) | if (strcmp(a,b) < 0) a 小於 b |
char *a = "hello";
char *b = "hello";
if (a == b) // 比較地址!可能真可能假(取決於編譯器常量池優化)
if (strcmp(a, b)) { /* 不相等時執行 */ } // 正確:非0即真
if (!strcmp(a, b)) { /* 相等時執行 */ } // 正確:取反
if (strcmp(a, b) == 1) { /* 錯誤!返回值不一定是1,可能是任意正數 */ }
<string.h>隱式聲明導致返回值截斷,64 位系統嚴重錯誤。
原代碼關鍵片段:
char giver[9][13], the_giver[13];
// ... 讀入數據 ...
people_judger = 0;
if (strcmp(the_giver, giver[people_judger]) != 0) {
people_judger++;
}
// 後續循環中同樣邏輯
問題: people_judger 僅在不相等時遞增**一次**,若前幾個名字都不匹配,無法遍歷整個數組找到正確索引。
int find_person(const char *name, char names[][13], int n) {
for (int i = 0; i < n; i++) {
if (strcmp(name, names[i]) == 0) { // 相等返回 0
return i; // 找到索引
}
}
return -1; // 未找到
}
// 使用
int idx = find_person(the_giver, giver, total_people);
if (idx == -1) { /* 錯誤處理 */ }
#include
#include
#include
#define MAX_P 10
#define MAX_NAME 13
int main() {
FILE *fin = fopen("gift1.in", "r");
FILE *fout = fopen("gift1.out", "w");
int np; fscanf(fin, "%d", &np);
char names[MAX_P][MAX_NAME];
int balance[MAX_P] = {0};
for (int i = 0; i < np; i++) fscanf(fin, "%s", names[i]);
for (int g = 0; g < np; g++) {
char giver_name[MAX_NAME];
fscanf(fin, "%s", giver_name);
int giver_idx = find_person(giver_name, names, np);
int amount, ng; fscanf(fin, "%d %d", &amount, &ng);
int give_each = (ng == 0) ? 0 : amount / ng;
int keep = amount - give_each * ng;
balance[giver_idx] += keep;
for (int i = 0; i < ng; i++) {
char recv_name[MAX_NAME];
fscanf(fin, "%s", recv_name);
int recv_idx = find_person(recv_name, names, np);
balance[recv_idx] += give_each;
}
}
for (int i = 0; i < np; i++) {
fprintf(fout, "%s %d\n", names[i], balance[i]);
}
fclose(fin); fclose(fout);
return 0;
}
<string.h>strcmp(a,b) == 0strcmp(a,b) != 0fscanf 讀取字符串自動跳過空白,適配題目格式
#include
#include
#include
std::vector names = {"dave", "laura", "owen"};
std::string giver = "laura";
auto it = std::find(names.begin(), names.end(), giver);
if (it != names.end()) {
int idx = it - names.begin(); // 直接用 == 比較,std::string 重載了運算符
}
C++ std::string 支持 == 直接比較內容,強烈建議 C++ 項目使用。