Char & String (C-style)
蔡銘軒 @ Sprout 2021 C/C++語法班

Dive Deeper


第一支程式
Credit: Peipei @ Sprout 2021
Dive Deeper

發生了什麼事情?
std::cout << "Hello World!" << std::endl;
"Hello World!"
{'H','e','l','l','o',' ','W','o','r','l','d','!'}
字串
字元
字元

字元

字元是一種資料型別
char c = 'H';
字元用單引號包起來
char c1 = 'A'; // ok char c2 = "A"; // error
字元

其實字元只是一個整數 (-128 ~ 127)
std::cout << (int)'H' << std::endl;
72
字元

'H' == 72
?
char a = 'H'; char b = 72; if (a == b) std::cout << "Same" << std::endl; else std::cout << "Oops..." << std::endl;
字元

為什麼
'H' == 72
常見字元:
'A': 65, 'B': 66, 'C': 67 , ... , 'Z': 90
'a': 97, 'b': 98, 'c': 99 , ... , 'z': 122
'0': 48, '1': 49, '2': 50 , ... , '9': 57
字元

ASCII 表背不起來...
其實我也不會啦哈哈
既然字元其實是整數,當然也可以做運算
char b = 'a' + 1; // b is 'b' char Z = 'A' + 25; // Z is 'Z' char one = '2' - 1; // one is '1';
字元

特殊字元之跳脫字元 (credit: Arvin Liu)
常見特殊字元 | 表示方法 |
---|---|
換行 | '\n' |
水平定位 | '\t' |
字串結尾 | '\0' |
' | '\'' |
\ | '\\' |
" | '\"' |
回車 |
'\r' |
倒退 | '\b' |
字串

字串

字元就是字元陣列
char s[6] = "Hello";
字元用雙引號包起來
char s1[2] = "A"; // ok char s2[2] = 'A'; // error
字串

長度+1?
char s[6] = "Hello";
"Hello"長度只有5,為什麼陣列長度宣告6?
字串

隱藏的'\0'
char s[6] = "Hello";
char s[6] = {'H','e','l','l','o','\0'};
上面兩者是相同的!
電腦偷偷幫你放了一個'\0'在最後面
'\0'代表一個字串的結束
題外話:'\0'對應的整數就是0
字串

字串初始化
char s1[6] = "Hello"; // ok
char s2[6] = {'H', 'e', 'l', 'l', 'o', 0}; // ok
char s[6] = "Hello"; // ok
s = "World"; // error
s = {'W', 'o', 'r', 'l', 'd', '\0'}; // error
字串只有在宣告的時候可以直接賦值
宣告後不能再用 '=' 去更改字串內容
字串

字串的輸出
char s[6] = "Hello";
std::cout << s << std::endl;
cout 將字串(字元陣列)裡的字元一一印出,
直到遇到'\0'才停止
字串

惡搞輸出
char a[5] = {'H', 'e', 'l', 'l', 'o'}; char b[6] = "World"; std::cout << a << std::endl; std::cout << b << std::endl;
執行結果:
HelloWorld
World
字串a沒有'\0'結尾,因此cout印出額外內容
執行結果在不同電腦上可能不同
字串

字串的輸入
輸入
Hello World
程式碼
char s[100]; std::cin >> s; std::cout << s << std::endl;
輸出
Hello
字串的輸入以空白為分界
常見空白字元: ' ', '\t', '\n'
字串常用函式

#include <cstring>

字串常用函式
strlen(char[] s)
回傳字串的長度,以'\0'為依據
char s[100] = "Sprout"; std::cout << strlen(s) << std::endl;
輸出
6

字串常用函式
strlen(char[] s)
使用注意事項:不要放在for迴圈的條件裡
把這個
char s[100] = "Sprout"; for (int i = 0; i < strlen(s); i++) std::cout << s[i] << std::endl;
改成這個
char s[100] = "Sprout"; int len = strlen(s); for (int i = 0; i < len; i++) std::cout << s[i] << std::endl;

字串常用函式
strcmp(char[] a, char[] b)
判斷兩個字串是否相等
若兩個字串相等則回傳0,否則回傳非0
char a[100] = "same"; char b[100] = "same"; if (strcmp(a, b) == 0) { std::cout << "same strings" << std::endl; } else { std::cout << "different" << std::endl; }

字串常用函式
strcpy(char[] dest, char[] src)
把字串src複製到dest裡
記得以下這樣是錯誤的
char a[100] = "old"; a = "new";
應該這樣寫
char a[100] = "old"; strcpy(a, "new"); // now a is "new"
記得dest要留一個位置給電腦偷偷幫你放的'\0'

字串常用函式
strcat(char[] dest, char[] src)
把字串src接到dest後面
字串之間沒有加法的運算
char a[100] = "front"; a += "back"; // error
應該這樣寫
char a[100] = "front"; strcpy(a, "back"); // a is now "frontback"
記得dest要留一個位置給電腦偷偷幫你放的'\0'

課堂練習
Copy of Sprout 2021 C-style string
By allen522019
Copy of Sprout 2021 C-style string
- 260