一、strcmp —— 字符串比較(區分大小寫)

int strcmp(const char *s1, const char *s2);

字典序 比較兩個字符串(ASCII)

返回值

含義

= 0

相等

< 0

s1 < s2

> 0

s1 > s2

strcmp("abc", "abc"); // 0
strcmp("abc", "abd"); // < 0
strcmp("abc", "Abc"); // > 0(區分大小寫)
  • 比較到 \0 為止
  • 不能傳 NULL

二、strncmp —— 限定長度的比較

int strncmp(const char *s1, const char *s2, size_t n);

最多比較 前 n 個字符

strncmp("abcdef", "abcxyz", 3); // 0
strncmp("abc", "abd", 3);       // < 0
  • 比較前綴
  • 避免超長字符串帶來的風險

三、_stricmp —— 不區分大小寫比較(Windows)

int _stricmp(const char *s1, const char *s2);
  • 忽略大小寫比較字符串
  • 僅 Windows / MSVC
_stricmp("ABC", "abc"); // 0

示例

#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 必須包含此頭文件以使用 strto... 系列函數

int main() {
	const char* str1 = "abcde";
	const char* str2 = "abCde";
	// 比較字符串
	//int result = strcmp(str1, str2); // 區分大小寫
	int result = strncmp(str1, str2, 3); // 最後一位代表比較前3個字符
	if (result == 0) {
		printf("str1 和 str2 相等\n");
	}
	else if (result < 0) {
		printf("str1 小於 str2\n");
	}
	else {
		printf("str1 大於 str2\n");
	}
	// 忽略大小寫比較
	//int result2 = strcasecmp(str1, str2); 
    // Android NDK → strcasecmp
    // Linux → strcasecmp
    // Windows + MSVC → _stricmp
	int result2 = _strcmpi(str1, str2); //  _strcmpi windows 下使用
	if (result2 == 0) {
		printf("str1 和 str2 相等 (忽略大小寫)\n");
	}
	else if (result2 < 0) {
		printf("str1 小於 str2 (忽略大小寫)\n");
	}
	else {
		printf("str1 大於 str2 (忽略大小寫)\n");
	}
	return 0;
}

輸出

str1 大於 str2                                                                                                          
str1 和 str2 相等 (忽略大小寫)

四、strstr —— 子串查找

char *strstr(const char *haystack, const char *needle);

在一個字符串中查找 第一次出現的子串

  • 找到:返回 指向子串起始位置的指針
  • 找不到:NULL
char *p = strstr("hello world", "world");
// p -> "world"

五、strcat —— 字符串拼接

char *strcat(char *dest, const char *src);

src 追加到 dest 後面

char buf[20] = "Hello ";
strcat(buf, "World");

不會檢查目標緩衝區大小!!!

char buf[10] = "Hello ";
strcat(buf, "World!!!"); // 緩衝區溢出

推薦替代

strncat(dest, src, sizeof(dest) - strlen(dest) - 1);

六、strcpy —— 字符串拷貝

char *strcpy(char *dest, const char *src);

src 拷貝到 dest

char buf[10];
strcpy(buf, "hi");

致命坑

char buf[4];
strcpy(buf, "hello"); // 直接溢出

推薦替代

strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';

示例

#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 必須包含此頭文件以使用 strto... 系列函數

int main() {
	const char* str1 = "Name is Xaye";
	const char* str2 = "X";
	// 查找子字符串
	const char* found = strstr(str1, str2); // 返回子字符串首次出現的位置(地址),否則返回 NULL
	if (found != NULL) {
		printf("找到了子字符串: %s\n", found); // Xaye
	}
	else {
		printf("未找到子字符串\n");
	}
	// 求子字符串首次出現的位置索引
	if (found != NULL) {
		int index = found - str1; // 指針相減得到索引
		printf("子字符串首次出現的位置索引: %d\n", index); // 8
	}
	else {
		printf("未找到子字符串,無法計算索引\n");
	}
	

	// 拼接字符串
	char dest[50] = "Welcome to ";

	strcat(dest, str2); // Windows 下使用 strcat_s , Linux 下使用 strcat
	// 或者在 項目-屬性-C/C++-預處理器 定義 _CRT_SECURE_NO_WARNINGS 來禁用安全警告 就可以使用 strcat了
	printf("拼接後的字符串: %s\n", dest); // Welcome to X

	// 拷貝字符串
	char dest1[20];
	strcpy(dest1, "Hello Xaye!");
	printf("拷貝後的 dest1: %s\n", dest1); // Hello Xaye!

	return 0;
}

輸出

找到了子字符串: Xaye                                                                                                    
子字符串首次出現的位置索引: 8                                                                                           
拼接後的字符串: Welcome to X                                                                                            
拷貝後的 dest1: Hello Xaye!