在C語言中,字串(string)其實是以字元陣列來表示的。在程式中,一個字串通常以 '\0'
(ASCII碼為0的字元) 作為結束標記。
例如:
char str[] = "Hello";
編譯器會自動在陣列尾巴加上一個 '\0'
,實際記憶體佈局為:
{'H', 'e', 'l', 'l', 'o', '\0'}
上述 str
的型態是 char [6]
,含5個可見字元加上1個字串結尾字元。
當然,你也可以照樣宣告字元陣列:
char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};
然後我們可以修改 str
內的字元:
str[0] = 'a'; // 允許,變成 "aello"
printf("%s\n", str); // 輸出: aello
現在若你宣告一個指標指向str
:
char *p = str;
此時 p
是 char *
型態。
p
指向 str[0]
這個字元。str
)在表達式中會自動轉換為指向起始元素的指標,也就是 char *
,指向 str[0]
。透過 p
你可以使用指標運算來存取字串中的每個字元:
#include <stdio.h>
int main() {
char str[] = "Hello";
char *p = str;
printf("%c\n", *str); // 輸出 'H'
printf("%c\n", *p); // 輸出 'H'
printf("%c\n", *(p+1)); // 輸出 'e'
printf("%s\n", str); // 輸出 'Hello' //直接輸出字元陣列 str(會從 str[0] 開始,直到遇到 '\0' 為止)
printf("%s\n", p); // 輸出 'Hello' //行為與 str 相同
printf("%s\n", str+1); // 輸出 'ello' // str+1 表示從 str[1] 開始,輸出 "ello"
printf("%s\n", p+2); // 輸出 'llo' // p+2 表示從 str[2] 開始,輸出 "llo"
return 0;
}
'\0'
字元讓程式知道字串到此結束。C語言中有一些由標準函式庫提供的許多字串操作函式,這些函式定義在 <string.h>
中。
常見的字串函式如下:
strlen()
'\0'
結尾字元)。#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello";
printf("Length: %zu\n", strlen(str)); // 輸出 5
return 0;
}
strcpy()
src
字串複製到 dest
,含結尾的 '\0'
。使用者必須確保 dest
有足夠空間。char source[] = "Hello";
char destination[20];
strcpy(destination, source);
// destination 內容變成 "Hello"
strcat()
將 src
字串接續在 dest
字串的尾巴。dest
必須有足夠空間,且本身必須是一個有效字串(結尾有 '\0'
),strcat
會找到 dest
尾端後開始複製 src
。
範例:
char dest[20] = "Hello";
char src[] = " World";
strcat(dest, src);
// dest 內容變成 "Hello World"
strcmp()
字串比較,逐字元比較 s1
與 s2
的ASCII碼值,注意,是逐字元作比較。
回傳值:
範例:
int result = strcmp("apple", "banana"); // a < b => result = -1
strncpy
, strncat
等加上 'n'
的版本是有長度限制的版本。
strncpy()
複製局部的字元陣列。
範例 :
#include <stdio.h>
#include <string.h>
int main() {
// 1. 初始化源字串 src 和目標陣列 dest
char src[] = "Hello !"; // src 是一個包含字串 "Hello !" 的陣列,實際大小為 8(包含 '\0')
char dest[20] = "abcdefghijk"; // dest 是一個長度為 20 的字元陣列,初始值為 "abcdefghijk"
// 2. 使用 strncpy 將 src 的前 3 個字元複製到 dest 的前 3 個字元,dest 中的其餘部分保持不變
strncpy(dest, src, 3);
// src 的前 3 個字元是 "Hel",所以 dest 的前 3 個字元會被覆蓋成 "Hel"
// 原來的 dest = "abcdefghijk" 變成了 "Heldefghijk"("defghijk" 保持不變,因為沒有被覆蓋)
printf("src: %s\n", src); // 輸出 src: Hello !
printf("dest: %s\n", dest); // 輸出 dest: Heldefghijk
// 3. 使用 strncpy 將 src 的前 7 個字元(包含空白字元)複製到 dest 的前 7 個字元
strncpy(dest, src, 7);
// src 的前 7 個字元是 "Hello !"(包含空白字元)
// 這次 dest 的前 7 個字元會被覆蓋為 "Hello !",其餘未被覆蓋的部分 "hijk" 保持不變
// 原來的 dest = "Heldefghijk" 變成了 "Hello !hijk"
printf("src: %s\n", src); // 輸出 src: Hello !
printf("dest: %s\n", dest); // 輸出 dest: Hello !hijk
// 4. 使用 strncpy 複製 src 的前 8 個字元到 dest,這超出了 src 的實際長度
strncpy(dest, src, 8);
// src 只有 7 個可見字元和 1 個結束符 '\0',這次複製的 n 是 8
// 當 n = 8 時,strncpy 會嘗試將 src 的 8 個字元複製到 dest
// 由於 src 中的第 8 個字元是 '\0',strncpy 會將它一併複製到 dest
// 最後 dest 的前 8 個字元變成了 "Hello !\0",而後續的 "hijk" 仍然存在
// 但因為 '\0' 是字串的結束符,printf 只會輸出到 '\0' 為止,所以輸出會是 "Hello !"
printf("src: %s\n", src); // 輸出 src: Hello !
printf("dest: %s\n", dest); // 輸出 dest: Hello !
return 0;
}
strncat
將 src
字串的前 n 個字元追加到 dest
字串的後面。
範例 :
#include <stdio.h>
#include <string.h>
int main() {
char src[] = " World!";
char dest[20] = "Hello"; // dest 預先定義為 "Hello"
// 使用 strncat 連接 src 的前 3 個字元到 dest
strncat(dest, src, 3); // 只將 " Wo" 連接到 dest
printf("src: %s\n", src);
printf("dest: %s\n", dest);
return 0;
}
/* 輸出
src: World!
dest: Hello Wo
*/