#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')
n 大於任一字串實際長度,函數會讀取 \\0 之後的記憶體(若未以 \\0 結尾則為 UB)。建議傳入 strlen(s1) 或明確長度。strnicmp 通常僅處理 ASCII 字元 (A-Z/a-z)。非 ASCII 字元(如中文、帶音符字母)的大小寫轉換行為取決於當前 Locale (setlocale) 及實現。嚴格跨平台需用 ICU 庫或自行處理 Unicode。strncasecmp。建議在頭檔中統一:
#if defined(_WIN32) || defined(__TURBOC__)
#define STRNICMP strnicmp
#else
#define STRNICMP strncasecmp
#endif
stricmp / strcmpi:不區分大小寫比較整個字串 (直到 \\0)。strncmp:區分大小寫比較前 n 字元。memcmp:比較記憶體區塊 (二進制比較)。strncasecmp:POSIX 標準同功能函數。