在一對雙引號 " 之內可以放任意長度的字元 (包括長度為 0, 也包括跳脫字串),成為一個常數字串。常數字串自動以 NUL 字元結束。 若在宣告 char 型態的序列時,順便以一個常數字串來定義它的值, 則 C 會自動計算那常數字串的字元數 (包括 NUL 字元),而決定該序列的維度。 使用標準外部函式 strlen() (string length) 可以計算字串長度 (不含 NUL 字元)。看以下原始碼:
#include <stdio.h> #include <string.h> /* 示範 strlen() 的用法 (test-strlen.c) */ main() { char s[] = "hello, world.\n"; printf("%d:%s", strlen(s), s); }
14:hello, world.此時 s[] 的序列維度是 15 (包含 LF 和 NUL), 而字串長度則定義為 14 (包含 LF,不含 NUL)。
我們已經知道,C 不會代為看守序列的維度範圍。 所以您可以將 s[] 序列的編號寫到 15 以後。 例如以下程式,運氣好的時候會正確執行,輸出
19:hello, world! MORE但是運氣不好意思的時候,會發生不可預期的結果。謹記不要犯這種錯。
#include <stdio.h> #include <string.h> /* 錯誤示範,請勿模倣 */ main() { char s[] = "hello, world.\n"; s[12]='!'; s[13]=' '; s[14]='M'; s[15]='O'; s[16]='R'; s[17]='E'; s[18]='\n'; s[19]='\0'; printf("%d:%s", strlen(s), s); }
前面我們在檔頭部分,多寫了一個 #include <string.h>, 這個指令宣告了一些處理字串的標準外部函式。 前面我們已經看到 strlen() 的用法。 除此之外還有 19 個這類函式。以下再介紹 3 個,其他的函式會在以後陸續出現。
首先介紹 strcpy() (string copy): 它的用法是 strcpy(s, t),其中 s 和 t 都是字串, 但 s 必須是宣告了足夠維度的 char 序列變數, 而 t 可以是一個常數字串。 在 strcpy() 執行後,t 不會改變, 而 s 就變成了 t。 所以 strcpy(s,t) 就是將 t copy 到 s 的意思。
以前我們已經知道,下面這個語法是不正確的:
char s[20]; s = "hello, world.";而前面說了,一個方便的例外是,在宣告的時候可以順便定義序列的值,例如
char s[20]="hello, world.";卻是可以的。以下程式示範如何用 strcpy() 改變字串的內容。 但要特別注意,s[] 的維度足夠 (還要留一個位置給 NUL)。
#include <stdio.h> #include <string.h> /* 示範 strcpy() 的用法 (test-strcpy.c) */ main() { char s[20]="hello, world."; printf("%s\n", s); strcpy(s, "this is a C."); printf("%s\n", s); }
hello, world. this is a C.
其次介紹 strcat()。它的呼叫格式仍是 strcat(s, t), 其中 s 和 t 的意義與 strcpy() 相同, 但執行的結果是將 t 字串銜接到 s 的後面。
最後介紹 strcmp。它的呼叫格式是 strcmp(s, t), 但是此函式不會改變 s 和 t 的內容, 只會回應一個整數。若 s 和 t 是相同的兩個字串, 回應 0。否則,回應可能是正數,也可能是負數。 若回應正數,代表 s > t, 否則就是 s < t。 而字串的大小,就是按照一般英文字典裡面的排序法, 也就是 UNIX 的 sort 指令的排序法。 譬如 "abort" < "about" 而 "Schumann" > "Schubert"。
注意,因為當 s 和 t 相同的時候,回應的數是 0。 所以,若要用在 for、while、if 的條件語句內時, s 和 t 相同反而會成為 False。 因此要用 !strcmp(s,t) 來偵測 s 和 t 是相同的。
習題
#include <stdio.h> #include <string.h> main() { char s[10]="abort", t[10]="about"; printf("%d\n", strcmp(s,t)); strcpy(s, "Schumann"); strcpy(t, "Schubert"); printf("%d\n", strcmp(s,t)); }
#include <stdio.h> #include <string.h> #define BUFSIZE 256 int getline(char[], int); main() { char buf[BUFSIZE]; int n=0; while (getline(buf, BUFSIZE) > 0) if(!strcmp(buf, "1234\n")) ++n; printf("%d\n", n); }
105633-36 106437-03 106522-03 106569-01 106592-03則輸出變成
105633-36 106437-03 106522-03 106569-01 106592-03
注意:此處所有文件均為原著,個別的版權宣告日後會一一公布, 整體版面設計亦尚未完成。但仍請勿抄襲文字與圖片,以免觸犯著作權法。
Created: May 14, 2000
Last Revised: May 14, 2000
© Copyright 2000 Wei-Chang Shann 單維彰