首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言字符串比較:strcmp 正確用法與常見誤區

     編輯:程式設計綜合問答

C 語言中字符串**不能**用 == 或 != 比較,必須使用 strcmp。本文詳細說明 strcmp 返回值含義、正確判斷邏輯,並分析 USACO 「貪婪送禮」題目中的比較錯誤。

strcmp 原型與語義


#include 
int strcmp(const char *str1, const char *str2);
返回值含義邏輯判斷
0str1 == str2 (內容相等)if (strcmp(a,b) == 0) 相等
> 0str1 > str2 (字典序)if (strcmp(a,b) > 0) a 大於 b
< 0str1 < str2 (字典序)if (strcmp(a,b) < 0) a 小於 b

常見錯誤

錯誤 1:用 == 比較字符串指針


char *a = "hello";
char *b = "hello";
if (a == b) // 比較地址!可能真可能假(取決於編譯器常量池優化)

錯誤 2:strcmp 返回值邏輯反了


if (strcmp(a, b)) { /* 不相等時執行 */ } // 正確:非0即真
if (!strcmp(a, b)) { /* 相等時執行 */ }   // 正確:取反
if (strcmp(a, b) == 1) { /* 錯誤!返回值不一定是1,可能是任意正數 */ }

錯誤 3:未包含 <string.h>

隱式聲明導致返回值截斷,64 位系統嚴重錯誤。

USACO 題目代碼錯誤分析

原代碼關鍵片段:


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;
}

最佳實踐總結

  1. 必須包含 <string.h>
  2. 比較相等:strcmp(a,b) == 0
  3. 比較不等:strcmp(a,b) != 0
  4. 查找數組:封裝線性查找函數
  5. 輸入處理:fscanf 讀取字符串自動跳過空白,適配題目格式
  6. 邊界檢查:數組大小、文件指針、返回值

C++ 替代方案


#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++ 項目使用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved