1、定義字符串
C語言本身沒有string類型,通常使用char數組來表示字符串。常用的定義字符串的方式有:
char str1[] = {'C', 'h', 'i', 'n', 'a'};
char str2[] = "China";
char* str3 = "China";
-
與Java語言不同,C語言中數組的括號是在變量名的后面。第一條定義字符串的語句等價於Java語言中:
char[] str1 = {'C', 'h', 'i', 'n', 'a'};
-
[]
中可以填入數字,表示char數組的長度。但是,中括號中的數字必須大於等於右邊字符串數組的長度。char str1[5] = {'C', 'h', 'i', 'n', 'a'}
,char str1[6] = {'C', 'h', 'i', 'n', 'a'}
, ... ,char str1[100] = {'C', 'h', 'i', 'n', 'a'}
都是合法的。char str2[6] = "China";
,char str2[7] = "China";
, ... ,char str2[100] = "China";
都是合法的。,如果 str2 括號內填寫的數字小於 6 就會編譯出錯,出現數組界限溢出錯誤。char str2[5] = "China";
2、計算char數組的長度
在Java中,數組是看作對象類型的,數組有通用的屬性 length,比如 str1.length
可以獲取數組的長度。但是 C 語言可沒有這么“友善”,想獲取char數組的長度:
char str1[] = {'C', 'h', 'i', 'n', 'a'};
int len = sizeof(str1) / sizeof(char); // 這句話計算字符串數組的長度
printf("%d", len);
-
sizeof
是C語言中保留關鍵字,用來計算數據類型的“寬度”。用 sizeof 可以獲得數據類型或變量在內存中所占的字節數。同樣,用 sizeof 也可以獲得整個數組在內存中所占的字節數。 -
因為數組中每個元素的類型都是一樣的,在內存中所占的字節數都是相同的,所以 總的字節數 除以 一個元素所占的字節數 就是數組的長度。
-
sizeof(char)
表示數據類型 char 在內存中所占的字節數,在C語言中,char占一個字節,所以sizeof(char) == 1
。 -
我這里說的字符串數組的長度,說到底還是數組的長度。
3、字符串必須以\0結尾。如果不是,就會出現亂碼
char str1[] = { 'C', 'h', 'i', 'n', 'a' };
printf("%s\n", str1);
-
上面這段代碼在 Windows 上,用 Microsoft Visual Studio 運行時,會輸出亂碼。如圖所示:
-
C語言是一直讀取到字節
0
作為字符串的結尾。Java則可以根據數組長度屬性length,來讀取指定長度的字符串。
-
所以,正確的定義方式應該是
char str1[] = { 'C', 'h', 'i', 'n', 'a', '\0'};
,此時字符串數組的長度是 6。char str1[] = { 'C', 'h', 'i', 'n', 'a', 0 };
這樣定義也是可以的,但是更推薦前一種。
4、定義一個空的字符串數組
char str0[100] = {0}; // 用這條語句定義一個空的字符串數組
int len0 = sizeof(str0) / sizeof(char);
printf("%d", len0); // 數組長度為100
-
第一條語句就等同於Java中的
char[] str0 = new char[100];
-
第一句語句也可以寫成
char str0[100] = {};
,這樣寫也是正確的。但是,這樣寫不行,空初始值設定項對於未指定綁定的數組無效!char str0[] = {}
5、計算字符串的長度 strlen
與字符串數組的長度不同,字符串的長度是不把字節0算進去的。strlen
函數可以返回字符串的長度:
size_t strlen(const char* str);
然后來看幾個實驗:
char str1[] = {'C', 'h', 'i', 'n', 'a'};
char str2[] = "China";
char* str3 = "China";
char str4[] = {'C', 'h', 'i', 'n', 'a', '\0'};
printf("%d\n", strlen(str1)); // 輸出結果為19
printf("%d\n", strlen(str2)); // 輸出結果為5
printf("%d\n", strlen(str3)); // 輸出結果為5
printf("%d\n", strlen(str4)); // 輸出結果為5
- 其中,str1 所表示的字符串因為沒有以 '\0' 結尾,所以,
strlen
把內存中一直到\0
結尾的字節都看作字符串的內容,所以長度為 19。
6、字符串常量不可修改
我們先來看一段程序:
char str0[] = {'c', 'h', 'i', 'n', 'a', '\0'};
char str1[] = "china"; // 在棧上,因為重載了=操作符
char* str2 = "china"; // china\0在常量區,str1在棧上
str0[0] = 'C';
str1[0] = 'C';
//str2[0] = 'C';
//*str2 = 'C';
printf("%s\n", str0);
printf("%s\n", str1);
printf("%s\n", str2);
-
運行結果是,
str0[0] = 'C'
和str1[0] = 'C'
這兩句可以正常運行。但是str2[0] = 'C'
和*str2 = 'C'
會報錯。
-
char str1[] = "china"
和char* str2 = "china"
字符串存放的內存區域不同:前者存放在棧中,可以修改;后者存放在常量區,不可修改。 -
0xC0000005
:安全點就是通過這個技術暫停所有線程的。
7、拷貝字符串strcpy
C語言 strcpy() 函數用於對字符串進行復制(拷貝)。
頭文件:string.h
語法/原型:
char* strcpy(char* strDestination, const char* strSource);
參數說明:
- strDestination:目的字符串。
- strSource:源字符串。
strcpy() 會把 strSource 指向的字符串復制到 strDestination。
必須保證 strDestination 足夠大,能夠容納下 strSource,否則會導致溢出錯誤。
返回值:目的字符串,也即 strDestination。
示例:
#include <string.h>
int main() {
char dest[] = {0};
char src[] = "Hello, Han Meimei!";
strcpy(dest, src);
printf("%s", dest);
return 0;
}
8、連接字符串strcat
頭文件:string.h
語法:
char* strcat(char* strDestination, const char* strSource);
參數說明:
- strDestination:目的字符串;
- strSource:源字符串。
strcat()
函數把 strSource 所指向的字符串追加到 strDestination 所指向的字符串的結尾,所以必須要保證 strDestination 有足夠的內存空間來容納兩個字符串,否則會導致溢出錯誤。
注意:strDestination 末尾的\0會被覆蓋,strSource 末尾的\0會一起被復制過去,最終的字符串只有一個\0。
返回值:指向 strDestination 的指針。
#include <string.h>
int main() {
char dest[] = "Hello";
char src[] = " World!";
strcat(dest, src);
printf("%s", dest);
return 0;
}
8、比較字符串strcmp
C語言 strcmp() 函數用於對兩個字符串的內容進行比較(區分大小寫)。
頭文件:string.h
語法/原型:
int strcmp(const char* stri1,const char* str2);
- 參數 str1 和 str2 是參與比較的兩個字符串。
strcmp() 會根據 ASCII 編碼依次比較 str1 和 str2 的每一個字符,直到出現不到的字符,或者到達字符串末尾(遇見\0)。
返回值:
- 如果返回值 < 0,則表示 str1 小於 str2。
- 如果返回值 > 0,則表示 str2 小於 str1。
- 如果返回值 = 0,則表示 str1 等於 str2。
示例:
#include <string.h>
int main() {
char str1[] = {'C', 'h', 'i', 'n', 'a', '\0'};
char* str2 = "China";
int result = strcmp(str1, str2);
printf("%d", result); // 輸出結果為0
return 0;
}
9、字符查找函數strchr
C語言 strchr() 函數用於查找給定字符串中某一個特定字符。
頭文件:string.h
語法/原型:
char* strchr(const char* str, int c);
參數說明:
- str:被查找的字符串。
- c:要查找的字符。
strchr() 函數會依次檢索字符串 str 中的每一個字符,直到遇見字符 c,或者到達字符串末尾(遇見\0)。
返回值:返回在字符串 str 中第一次出現字符 c 的位置,如果未找到該字符 c 則返回 NULL。
示例:
#include <string.h>
int main() {
char str1[] = {'C', 'h', 'i', 'n', 'a', '\0'};
printf("%p\n", str1);
char* p1 = strchr(str1, 'b');
printf("%p\n", p1); // 輸出結果為0,str1中不包含字符b
char* p2 = strchr(str1, 'h');
printf("%p\n", p2); // 輸出結果比 str1 的內存地址多一個字節
return 0;
}
運行結果如下圖所示:
10、查找子字符串strstr
C語言 strstr() 函數在字符串中查找子字符串。
語法/原型
char *strstr(const char *haystack, const char *needle)
參數說明:
- haystack -- 要被檢索的 C 字符串。
- needle -- 在 haystack 字符串內要搜索的小字符串。
返回值
該函數返回在 haystack 中第一次出現 needle 字符串的位置,如果未找到則返回 null。
示例:
char haystack[20] = "RUNOOB";
char needle[10] = "NOOB";
char *ret = strstr(haystack, needle);
printf("子字符串是: %s\n", ret);
return 0;
運行結果:
參考文檔
- Go to 《數組的長度,C語言獲取數組長度詳解》