教材準備
===
字串
---
> 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