函數 | 說明 |
strlen(str) | 傳回字串 str 的長度 (字元個數) |
strrev(str) | 將字串 str 反轉後傳回新字串之位址 |
strupr(str) | 將字串 str 轉成大寫後傳回新字串之位址 |
strlwr(str) | 將字串 str 轉成小後傳回新字串之位址 |
strchr(str, ch) | 從字串 str 頭開始尋找字元 ch, 傳回第一次出現的位址 |
strrchr(str, ch) | 從字串 str 尾開始尋找字元 ch, 傳回第一次出現的位址 |
strspn(s1, s2) | 比對兩個字串, 傳回第一次字元不同位置之索引 |
strcspn(s1, s2) | 比對兩個字串, 傳回第一次字元相同位置之索引 |
strstr(heystack, needle) | 從字串 needle 頭開始尋找字串 heystack, 傳回第一次出現的位址 |
strcpy(dest, source) | 將字串 source 的內容複製到字串 dest, 傳回目的字串 dest 位址 |
strncpy(dest, source, n) | 將字串 source 的內容複製 n 個字元到字串 dest, 傳回字串 dest 位址 |
strcat(dest, source) | 將字串 source 的內容串接到字串 dest 後面並傳回 dest 的位址 |
strcmp(s1, s2) | 比較字串 s1 與 s2 的內容, 相等傳回 0, s1 > s2 傳回正數, 否則負數 |
strtok(str, delim) | 將字串 str 以 delim 字串為分界符遞迴切割為子字串傳回 |
memset(str, ch, n) | 以 n 個 ch 字元填入字串 str 中, 傳回 str 位址 |
注意, 傳回值為位址的函數如 strrev() 等必須宣告一個 char 指標來儲存新字串之位址, 不可用 char 陣列. 參考 :
# https://zh.wikipedia.org/wiki/String.h
測試 1 : strlen(str)
此函數會傳回傳入字串 s1 的字元個數 (整數), 下列程式分別使用 scanf() 與 gets() 讀取輸入字串, scanf() 遇到空格就會停止讀取, 但 gets() 則不會, 會一直讀到跳行為止 (含); 除此之外 scanf() 不會讀入跳行字元 \n, 但 gets() 則會. 程式如下 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[256];
printf("請輸入字串\n"); //輸入 "Hello World"
scanf("%s", str); //用 scanf() 讀取會被空格中斷
printf("讀入字串=%s\n", str); //輸出 "Hello"
printf("字串長度=%d 個字元\n", strlen(str)); //輸出 5
gets(str); //用 gets() 讀取不會被空格中斷
printf("讀入字串=%s\n", str); //輸出 " World"
printf("字串長度=%d 個字元\n", strlen(str)); //輸出 6 (含前面一空格)
return 0;
}
執行結果如下 :
請輸入字串
Hello World
讀入字串=Hello
字串長度=5 個字元
讀入字串= World (注意, W 前面有一個空格)
字串長度=6 個字元
--------------------------------
Process exited after 9.066 seconds with return value 0
請按任意鍵繼續 . . .
測試 2 : strrev(str)
此函數會將傳入字串反轉, 並將反轉後之新字串開頭位址傳回, 故須定義一個 char 指標來儲存此位址. 程式如下 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[256], *nstr; //分別儲存原始字串與反轉後之字串
printf("請輸入字串\n");
gets(str);
printf("讀入字串=%s\n", str);
nstr=strrev(str); //須用 char 指標來儲存位址
printf("反轉字串=%s\n", nstr);
return 0;
}
執行結果 :
請輸入字串
Hello World
讀入字串=Hello World
反轉字串=dlroW olleH
--------------------------------
Process exited after 11.87 seconds with return value 0
請按任意鍵繼續 . . .
測試 3 : strupr(str)
此函數會將傳入字串之全部字元轉成大寫, 傳回此新字串之開頭位址, 因此必須定義一個 char 指標來儲存. 範例如下 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[256], *nstr; //分別儲存原始字串與大寫後之字串
printf("請輸入字串\n");
gets(str);
printf("讀入字串=%s\n", str);
nstr=strupr(str); //須用 char 指標來儲存位址
printf("大寫字串=%s\n", nstr);
return 0;
}
執行結果 :
請輸入字串
hello world
讀入字串=hello world
大寫字串=HELLO WORLD
--------------------------------
Process exited after 9.636 seconds with return value 0
請按任意鍵繼續 . . .
測試 4 : strlwr(str)
此函數會將傳入字串之全部字元轉成小寫, 傳回此新字串之開頭位址, 因此必須定義一個 char 指標來儲存. 範例如下 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[256], *nstr; //分別儲存原始字串與大寫後之字串
printf("請輸入字串\n");
gets(str);
printf("讀入字串=%s\n", str);
nstr=strlwr(str); //須用 char 指標來儲存位址
printf("小寫字串=%s\n", nstr);
return 0;
}
執行結果 :
請輸入字串
HELLO WORLD
讀入字串=HELLO WORLD
小寫字串=hello world
--------------------------------
Process exited after 7.496 seconds with return value 0
請按任意鍵繼續 . . .
測試 5 : strchr(str, ch)
此函數會從字串 str 頭開始尋找字元 ch, 找到的話傳回第一次出現的位址, 否則傳回 NULL. 將傳回位址減掉字串 str 之位址即為第一次出現的 ch 在 str 之索引, 例如 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[]="Hello World";
char *ptr;
printf("字串內容 %s\n", str);
for (int i=0; i<strlen(str); i++) {
printf("字元 '%c' 位址=%p\n", str[i], &str[i]);
}
ptr=strchr(str, 'o');
printf("第一個 o 出現位置之位址=%p\n", ptr);
printf("第一個 o 出現位置之索引=%d\n", ptr-str);
return 0;
}
執行結果 :
字串內容 Hello World
字元 'H' 位址=000000000062FE20
字元 'e' 位址=000000000062FE21
字元 'l' 位址=000000000062FE22
字元 'l' 位址=000000000062FE23
字元 'o' 位址=000000000062FE24
字元 ' ' 位址=000000000062FE25
字元 'W' 位址=000000000062FE26
字元 'o' 位址=000000000062FE27
字元 'r' 位址=000000000062FE28
字元 'l' 位址=000000000062FE29
字元 'd' 位址=000000000062FE2A
第一個 o 出現位置之位址=000000000062FE24
第一個 o 出現位置之索引=4
--------------------------------
Process exited after 0.07511 seconds with return value 0
請按任意鍵繼續 . . .
測試 6 : strrchr(str, ch)
此函數會從字串 str 尾開始尋找字元 ch, 找到的話傳回第一次出現的位址, 否則傳回 NULL. 將傳回位址減掉字串 str 之位址即為第一次出現的 ch 在 str 之索引, 例如 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[]="Hello World";
char *ptr;
printf("字串內容 %s\n", str);
for (int i=0; i<strlen(str); i++) {
printf("字元 '%c' 位址=%p\n", str[i], &str[i]);
}
ptr=strrchr(str, 'o');
printf("第一個 o 出現位置之位址=%p\n", ptr);
printf("第一個 o 出現位置之索引=%d\n", ptr-str);
return 0;
}
#include <string.h>
int main(void) {
char str[]="Hello World";
char *ptr;
printf("字串內容 %s\n", str);
for (int i=0; i<strlen(str); i++) {
printf("字元 '%c' 位址=%p\n", str[i], &str[i]);
}
ptr=strrchr(str, 'o');
printf("第一個 o 出現位置之位址=%p\n", ptr);
printf("第一個 o 出現位置之索引=%d\n", ptr-str);
return 0;
}
字串內容 Hello World
字元 'H' 位址=000000000062FE20
字元 'e' 位址=000000000062FE21
字元 'l' 位址=000000000062FE22
字元 'l' 位址=000000000062FE23
字元 'o' 位址=000000000062FE24
字元 ' ' 位址=000000000062FE25
字元 'W' 位址=000000000062FE26
字元 'o' 位址=000000000062FE27
字元 'r' 位址=000000000062FE28
字元 'l' 位址=000000000062FE29
字元 'd' 位址=000000000062FE2A
第一個 o 出現位置之位址=000000000062FE27
第一個 o 出現位置之索引=7
--------------------------------
Process exited after 0.08958 seconds with return value 0
請按任意鍵繼續 . . .
測試 7 : strspn(s1, s2)
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[]="Hello World";
char str2[]="Hello Tony";
size_t loc=strspn(str1, str2);
printf("第一個字元不同位置之索引=%d\n", loc);
return 0;
}
執行結果 :
第一個字元不同位置之索引=6
--------------------------------
Process exited after 0.09996 seconds with return value 0
請按任意鍵繼續 . . .
測試 8 : strcspn(s1, s2)
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[]="7777B333";
char str2[]="6666B222";
size_t loc=strcspn(str1, str2);
printf("第一個字元相同位置之索引=%d\n", loc);
return 0;
}
執行結果 :
第一個字元相同位置之索引=4
--------------------------------
Process exited after 0.08926 seconds with return value 0
請按任意鍵繼續 . . .
測試 9 : strstr(heystack, needle)
此函數會在 heystack 字串中從頭尋找第一個符合之子字串 needle, 找到的話將此起始位址傳回, 否則傳回 NULL. 顯示傳回位址所指內容即是此起始位置之後之子字串. 將傳回位址減掉 heystack 字串開頭位址即是符合字串在 heystack 中之索引.
#include <stdio.h>
#include <string.h>
char str[]="Hello World";
char *ptr;
printf("字串內容 %s\n", str);
for (int i=0; i<strlen(str); i++) { //顯示字串中各字元位址
printf("字元 '%c' 位址=%p\n", str[i], &str[i]);
}
ptr=strstr(str, "o");
printf("字串開頭位址=%p\n", str);
printf("第一個 o 出現位置之子字串=%s\n", ptr);
printf("第一個 o 出現位置之子字串位址=%p\n", ptr);
printf("第一個 o 出現位置之索引=%d\n", ptr-str);
return 0;
}
執行結果 :
字串內容 Hello World
字元 'H' 位址=000000000062FE20
字元 'e' 位址=000000000062FE21
字元 'l' 位址=000000000062FE22
字元 'l' 位址=000000000062FE23
字元 'o' 位址=000000000062FE24
字元 ' ' 位址=000000000062FE25
字元 'W' 位址=000000000062FE26
字元 'o' 位址=000000000062FE27
字元 'r' 位址=000000000062FE28
字元 'l' 位址=000000000062FE29
字元 'd' 位址=000000000062FE2A
字串開頭位址=000000000062FE20
第一個 o 出現位置之子字串=o World
第一個 o 出現位置之子字串位址=000000000062FE24
第一個 o 出現位置之索引=4
--------------------------------
Process exited after 0.1082 seconds with return value 0
請按任意鍵繼續 . . .
測試 10 : strcpy(dest, source)
此函數會將第二參數來源字串 source 的內容複製到第一參數目的字串 dest, 並傳回目的字串的位址.
#include <stdio.h>
#include <string.h>
int main(void) {
char source[]="Hello World";
char dest[20]={};
printf("來源字串 '%s'\n", source);
printf("目的地字串 '%s'\n", dest);
printf("來源字串位址 %p\n", source); //顯示來源字串位址
printf("目的地字串位址 %p\n", dest); //顯示目的地字串位址
strcpy(dest, source); //傳回 dest 字串之位址
printf("目的字串 '%s'\n", dest);
printf("目的地字串位址 %p\n", strcpy(dest, source)); //顯示目的地字串位址
return 0;
}
執行結果 :
來源字串 'Hello World'
目的地字串 ''
來源字串位址 000000000022FE40
目的地字串位址 000000000022FE20
目的字串 'Hello World'
目的地字串位址 000000000022FE20
--------------------------------
Process exited with return value 0
Press any key to continue . . .
測試 11 : strncpy(dest, source, n)
此函數會將第二參數來源字串 source 的內容複製 n 個字元到第一參數目的字串 dest, 並傳回目的字串 dest 的位址.
#include <stdio.h>
#include <string.h>
int main(void) {
char source[]="Hello World";
char dest[20]={};
printf("來源字串 '%s'\n", source);
printf("目的地字串 '%s'\n", dest);
printf("來源字串位址 %p\n", source); //顯示來源字串位址
printf("目的地字串位址 %p\n", dest); //顯示目的地字串位址
strncpy(dest, source, 7); //傳回 dest 字串之位址 (複製 7 個字元)
printf("目的字串 '%s'\n", dest);
printf("目的地字串位址 %p\n", strcpy(dest, source, n)); //顯示目的地字串位址
return 0;
}
執行結果 :
來源字串 'Hello World'
目的地字串 ''
來源字串位址 000000000062FE40
目的地字串位址 000000000062FE20
目的字串 'Hello W'
目的地字串位址 000000000062FE20
--------------------------------
Process exited after 0.09536 seconds with return value 0
請按任意鍵繼續 . . .
目的地字串 ''
來源字串位址 000000000062FE40
目的地字串位址 000000000062FE20
目的字串 'Hello W'
目的地字串位址 000000000062FE20
--------------------------------
Process exited after 0.09536 seconds with return value 0
請按任意鍵繼續 . . .
測試 12 : strcat(dest, source)
此函數會將字串 source 的內容串接到字串 dest 後面並傳回 dest 的位址 (指標), 例如 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[20]="Hello";
char str2[20]=" World";
printf("'Hello' 位址=%p\n", str1); //顯示第一個字串位址
printf("' World' 位址=%p\n", str2); //顯示第二個字串位址
printf("strcat('Hello', ' World')=%s\n", strcat(str1, str2)); //串接後以第一個字串為結果
printf("strcat('Hello', ' World') 位址=%p\n", strcat(str1, str2)); //顯示第一個字串位址
return 0;
}
此程式中先顯示兩個串接字串在記憶體中之位址, strcat(dest, source) 函數以第一個字串作為結果字串, 因此傳回值為第一個字串之位址.
執行結果 :
' World' 位址=000000000062FE10
strcat('Hello', ' World')=Hello World
strcat('Hello', ' World') 位址=000000000062FE30 //串接後傳回第一個字串位址
--------------------------------
Process exited after 0.08643 seconds with return value 0
請按任意鍵繼續 . . .
測試 13 : strcmp(s1, s2)
#include <stdio.h>
#include <string.h>
int main(void) {
char str1[20]="Hello";
char str2[20]="hello";
printf("strcmp('Hello', 'Hello')=%d\n", strcmp(str1, str1));
printf("strcmp('Hello', 'hello')=%d\n", strcmp(str1, str2));
printf("strcmp('hello', 'Hello')=%d\n", strcmp(str2, str1));
return 0;
}
執行結果 :
strcmp('Hello', 'Hello')=0
strcmp('Hello', 'hello')=-1
strcmp('hello', 'Hello')=1
--------------------------------
Process exited after 0.09408 seconds with return value 0
請按任意鍵繼續 . . .
可見由於 H 的 ASCII 編碼數值 (72) 小於 h 的編碼 (104), 因此 strcmp('Hello', 'hello') 傳回 -1.
測試 14 : strtok(str, delim)
此函數會以字串 delim 為分界符號拆解字串 str, 傳回值為分界符前面之子字串, 若要全部拆解須用遞迴方式, 但遞迴時第一參數必須傳入 NULL, 例如 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[]="11:22:33:44:55:66"; //待拆解字串
char delim[]=":"; //分界符
char *tok; //儲存分界符前之子字串
printf("待拆解字串 %s\n", str);
printf("分界字串 %s\n", delim);
tok=strtok(str, delim); //第一次拆解
while (tok != NULL) { //遞迴拆解
printf("%s\n", tok); //輸出分界符前之子字串
tok=strtok(NULL, delim); //第二次拆解傳入 NULL
}
return 0;
}
執行結果 :
待拆解字串 11:22:33:44:55:66
分界字串 :
11
22
33
44
55
66
--------------------------------
Process exited with return value 0
Press any key to continue . . .
遞迴迴圈內的 strtok() 第一參數若傳入待拆解字串 str 會不斷地拆解第一個子字串而形成無窮迴圈, 務必要傳入 NULL, 參考 :
# 切割字串函數:strtok, Network mac address 分割
測試 15 : memset(str, ch, n)
此函數會以 n 個 ch 字元填入 str 字串中, 傳回值為 str 字串之位址 (指標). 在宣告字元陣列時可用字串 literal 例如 "0000000000" 或 {'0', '0', .... '0'} 初始化, 但是如果陣列很大的話就必須用 memset() 了. 例如 :
#include <stdio.h>
#include <string.h>
int main(void) {
char str[11];
memset(str, '0', 10); //填入 10 個 '0'
str[10]='\0'; //字串結尾字元
printf("%s\n", str);
for (int i=0; i<strlen(str); i++) {
printf("字元 '%c' 位址=%p\n", str[i], &str[i]);
}
return 0;
}
執行結果 :
0000000000
字元 '0' 位址=000000000022FE30
字元 '0' 位址=000000000022FE31
字元 '0' 位址=000000000022FE32
字元 '0' 位址=000000000022FE33
字元 '0' 位址=000000000022FE34
字元 '0' 位址=000000000022FE35
字元 '0' 位址=000000000022FE36
字元 '0' 位址=000000000022FE37
字元 '0' 位址=000000000022FE38
字元 '0' 位址=000000000022FE39
--------------------------------
Process exited with return value 0
Press any key to continue . . .
參考 :
# http://www.cplusplus.com/reference/cstring/memset/
# 字串比較、搜尋
# C語言字符串函數大全
# [C&++] 字串整數轉換
# C++字符串格式化 sprintf、printf
# [C/C++] cstring (string.h) 搜尋函式:strstr, strchr
# [C/C++] 切割字串函數:strtok, Network mac address 分割
# C語言編譯器哪個好?6款好用的C語言編譯器推薦