教材準備 === 字串 --- > C 其實沒有字串這個類別。 好,我們今天就上到這裡,下課。 <br><br><br><br><br><br><br><br><br><br> C++和Python其實都有```string```這個類別,不過C沒有,我們用**字元的陣列**來代表字串。 ### 基本用法 ```clike #include <stdio.h> int main() { char a[80]; scanf("%s", a); // 讀到空格或換行就結束。 printf("%s\n", a); char b[64] = "aloha", c[64] = "int main()\n{\n}\n"; // 字串的初始化要用雙引號 " " printf("%s\n%s\n", b, c); return 0; } ``` 問題就來了。```b```的長度是64,aloha只有5個字,當你在```printf```的時候編譯器是怎麼知道你的字串已經結束? 還記得上次提到的ASCII表嗎?ASCII表的第一個字元 NULL就是 ```\0```,字串處理函式遇到```\0```就知道字串已經結束。 小練習:如果你要存一個最多100個字的字串,你的字元陣列最少要開多大? * 注意: 字串的題目很多時候出bug都是因為最後的```\0```沒有處理好。 ### 其他寫法 這些是課本有提到不過我個人覺得比較少用到的寫法 ```clike char a[] = "aloha" // 沒說長度,讓編譯器自己算。 char *b = "aloha" // 字元指標 ``` ### 常用函式 首先,你必須```#include <string.h>```。 1. strlen 給定一個字串,回傳字串的長度 ```clike #include <string.h> #include <stdio.h> int main() { char a[80]; scanf("%s", a); printf("%lu\n", strlen(a)); return 0; } ``` 小練習:自己實作```strlen```函式。 2. strcpy, strncpy, strcat, strncat ```strcpy```會把source字串複製並**覆蓋**到destination。strncpy做的事情也一樣,只是你需要多給一個參數說你想複製多少個字元。 ```clike #include <string.h> #include <stdio.h> int main() { char source[80] = "aloha", destination[80] = "hello"; strcpy(destination, source); printf("%s\n", destination); return 0; } ``` ```strcat```會把source字串複製並**接到**destination。strncat做的事情也一樣,只是你需要多給一個參數說你想複製多少個字元。 ```clike #include <string.h> #include <stdio.h> int main() { char source[80] = "aloha", destination[80] = "hello"; strcat(destination, source); printf("%s\n", destination); return 0; } ``` * 注意:編譯器不會幫你檢查複製/接上的結果會不會超過目標字元陣列的大小,超過的部分會被吃掉,這也就是所謂緩衝區覆蓋(buffer overrun) 3. strcmp, strncmp 比較兩個字串是否相同,相同的話回傳0,前者比後者“大”回傳正數,後者比回傳“大”回傳負數。 大小是用ASCII表作為標準。 strncmp做的事情也一樣,只是你需要多給一個參數說你想比對前幾個字元。 ```clike #include <string.h> #include <stdio.h> int main() { printf("%d\n", strcmp("aloha", "hello")); printf("%d\n", strcmp("aloha", "aloha")); return 0; } ``` 小練習:讀入兩個字串,檢查這兩個字串是否相同,字串的長度 < 64。 4. strchr, strrchr, strstr strchr在字串中搜尋一個字元c, 如果找的到就回傳第一個字元c的記憶體位置。 strrchr也是一樣,不過就是反著找。 strstr也是一樣,不過是在字串裡面找字串。 ```clike #include <string.h> #include <stdio.h> int main() { char a[80] = "helloaloha"; char *ptr = strchr(a, 'a'); printf("%lu\n", ptr - a); return 0; } ``` 5. strtok strtok會把字串切成一段一段的token。token就是字串被delimeters中的任何字元所隔開的部分。 strtok的用法很特別,分為3個步驟。 * 先呼叫strtok一次。```token = strtok(string, delimeters)``` 會把string切成很多個token並指定給定一個指標token。每個token都會在最後被塞入一個\0,可以用各種字串函式處理。 * 進入while迴圈檢查token是否為NULL,然後作處理。 * 呼叫多一次strtok ```strtok(NULL, delimeters)```跳到下一個token。 ```clike #include <string.h> #include <stdio.h> int main() { char a[80] = "welcome,to,facebook.mark.zuckerberg"; char *token; token = strtok(a, ",."); while (token != NULL) { printf("%s\n", token); token = strtok(NULL, ",."); } return 0; } ``` 最後一份習題 --- 寫一份能印出自己的Code。 [Quine](https://en.wikipedia.org/wiki/Quine_(computing)) 例 : ```clike #include <stdio.h> int main() { char c;FILE *f; f=fopen(__FILE__,"r"); while((c=fgetc(f))!=EOF)putchar(c); } ``` 這個計程不會考,不過我覺得還蠻有趣的 XD