首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 標準庫函數詳解:strnicmp / strncmpi — 不區分大小寫比較前 N 個字元

     編輯:關於C語言

函數原型

#include <string.h>
int strnicmp(const char *s1, const char *s2, size_t n);
// strncmpi 通常是 strnicmp 的宏定義別名 (Microsoft/Visual C++ 常見)

注意:此函數為非標準 C(POSIX 標準為 strncasecmp),但在 Windows (MSVC)、Borland/Turbo C、部分嵌入式編譯器中廣泛可用。跨平台專案建議自行封裝或使用 strncasecmp (Linux/BSD) 配合宏切換。

功能描述

比較字串 s1 和 s2 的前 n 個字元,**忽略大小寫** (Case-Insensitive)。比較基於字元的 ASCII 數值(轉為大寫或小寫後比較)。

參數說明

  • s1、s2:待比較的字串指標。
  • n:最大比較字元數 (size_t 類型)。

返回值

  • < 0:s1 (前 n 字元) 小於 s2。
  • = 0:s1 (前 n 字元) 等於 s2。
  • > 0:s1 (前 n 字元) 大於 s2。

具體返回值通常為第一對差異字元的 ASCII 差值 (忽略大小寫後)。

範例程式碼

// strnicmp_demo.c
#include <stdio.h>
#include <string.h>
#include <ctype.h> // 用於手動實現跨平台版本

// 跨平台安全封裝範例
int my_strnicmp(const char *s1, const char *s2, size_t n) {
    if (n == 0) return 0;
    do {
        int c1 = tolower((unsigned char)*s1++);
        int c2 = tolower((unsigned char)*s2++);
        if (c1 != c2) return c1 - c2;
        if (c1 == 0) break; // 遇到結束符
    } while (--n > 0);
    return 0;
}

int main(void) {
    const char *s1 = "Hello, Programmers!";
    const char *s2 = "Hello, programmers!"; // 'P' vs 'p'
    int r;

    // 1. 比較完整長度 (忽略大小寫應相等)
    r = strnicmp(s1, s2, strlen(s1));
    printf("忽略大小寫比較全長: %d (預期 0)\n", r);

    // 2. 僅比較前 7 字元 "Hello, "
    r = strnicmp(s1, s2, 7);
    printf("比較前 7 字元: %d (預期 0)\n", r);

    // 3. 比較 "Apple" vs "apple" (指定長度 3)
    r = strnicmp("Apple", "apple", 3); // "App" vs "app" -> 相等
    printf("比較前 3 字元: %d\n", r);

    // 4. 區分大小寫對比
    r = strncmp(s1, s2, strlen(s1));
    printf("區分大小寫比較: %d (非 0, 因 'P' != 'p')\n", r);

    return 0;
}

執行結果

忽略大小寫比較全長: 0 (預期 0)
比較前 7 字元: 0 (預期 0)
比較前 3 字元: 0
區分大小寫比較: -32 (非 0, 因 'P' != 'p')

常見問題與最佳實踐

  1. 緩衝區溢出風險:若 n 大於任一字串實際長度,函數會讀取 \\0 之後的記憶體(若未以 \\0 結尾則為 UB)。建議傳入 strlen(s1) 或明確長度。
  2. Locale 敏感:標準 strnicmp 通常僅處理 ASCII 字元 (A-Z/a-z)。非 ASCII 字元(如中文、帶音符字母)的大小寫轉換行為取決於當前 Locale (setlocale) 及實現。嚴格跨平台需用 ICU 庫或自行處理 Unicode。
  3. 命名衝突:Linux/GCC 通常提供 strncasecmp。建議在頭檔中統一:
    #if defined(_WIN32) || defined(__TURBOC__)
    #define STRNICMP strnicmp
    #else
    #define STRNICMP strncasecmp
    #endif
    

相關函數

  • stricmp / strcmpi:不區分大小寫比較整個字串 (直到 \\0)。
  • strncmp:區分大小寫比較前 n 字元。
  • memcmp:比較記憶體區塊 (二進制比較)。
  • strncasecmp:POSIX 標準同功能函數。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved