char 字串
空字元(null character)
char字串必須以’\0’做結尾,若不是’\0’做結尾則稱為char陣列。
宣告字串,必須留1個字元,放結尾\0,以下宣告最多可以放5個字元,而第6個字元則是放\0。
char str[6];
以下二種宣告是完全不同,一個是字串,一個是陣列。
1
2
3
4
5
6
7
8
//char字串
// \0 代表結尾
char str1[6] = {'h','e','l','l','o','\0'};
cout << "str1 長度 = " << strlen(str1) << ",內容 = " << str1 << endl;
//char 陣列
char arr[6] = {'h','e','l','l','o','o'};
cout << "arr 長度 = " << strlen(arr) << ",內容 = " << arr << endl;
cout << "arr sizeof = " << sizeof(arr) << endl;
執行結果
str1 長度 = 5,內容 = hello
arr 長度 = 11,內容 = helloohello
arr sizeof = 6
字串常數
注意!以下”“雙引號包住的字串是常數,編譯器會自動加上’\0’作結尾,不用手動加’\0’。
1
2
//字串常數
char str1[] = "hello"
字串常數宣告
以下程式碼,cstr1沒有初始化字串常數,執行程式時會從cstr1的記憶體位址開始輸出值,直到遇到記憶體位址的值為\0(空字元)才會停止輸出,不會因為超過宣告字串的長度而停止印出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;
int main() {
char cstr1[21];//cstr1沒有初始化字串常數
//遇到記憶體位址的值為\0(空字元)才會停止輸出
cout << "cstr1 長度 = " << strlen(cstr1) << ",內容 = " << cstr1 << endl;
//以下結尾編譯器會自動加上\0
char cstr2[] = "hello";
cout << "cstr2 長度 = " << strlen(cstr2) << ",內容 = " << cstr2 << endl;
char cstr3[6] = "hello";
cout << "cstr3 長度 = " << strlen(cstr3) << ",內容 = " << cstr3 << endl;
char cstr4[] = {"hello"};
cout << "cstr4 長度 = " << strlen(cstr4) << ",內容 = " << cstr4 << endl;
char cstr5[6] = {"hello"};
cout << "cstr5 長度 = " << strlen(cstr5) << ",內容 = " << cstr5 << endl;
char cstr6[6] {"hello"};
cout << "cstr6 長度 = " << strlen(cstr6) << ",內容 = " << cstr6 << endl;
//設為nullptr
char cstr7[6] = {0};
cout << "cstr7 長度 = " << strlen(cstr7) << ",內容 = " << cstr7 << endl;
return 0;
}
執行結果
cstr1 長度 = 6,內容 = p\364\357\277\367
cstr2 長度 = 5,內容 = hello
cstr3 長度 = 5,內容 = hello
cstr4 長度 = 5,內容 = hello
cstr5 長度 = 5,內容 = hello
cstr6 長度 = 5,內容 = hello
cstr7 長度 = 0,內容 =
字串清空
使用memset,第二個參數設為0,代表把字串的記憶體位址的值全設為\0。
1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
int main() {
char cstr2[] = "hello";
cout << "cstr2 長度 = " << strlen(cstr2) << ",內容 = " << cstr2 << endl;
memset(cstr2,0,sizeof(cstr2));
cout << "cstr2 長度 = " << strlen(cstr2) << ",內容 = " << cstr2 << endl;
return 0;
}
執行結果
cstr2 長度 = 5,內容 = hello
cstr2 長度 = 0,內容 =
字串拷貝 strcpy
char * strcpy ( char * destination, const char * source );
要從來源的字串,拷貝到目的字串。
- 參數1:目的字串(拷貝到那裡?)
- 參數2:來源字串(要拷貝的字串)
拷貝完成後,會自動在目的字串最後面加上\0。
1
2
3
4
char c_str1[6] = {'h','e','l','\0'};
char c_str4[20] = {'t','e'};
strcpy(c_str4, c_str1);
cout << "c_str4:" << c_str4 << endl;
執行結果
c_str4:hel
字串指標拷貝 strcpy
1
2
3
4
5
6
char* c_str1 = new char[100];
strcpy(c_str1, "abcdefg");
char* c_str2 = new char[100];
strcpy(c_str2, c_str1);
cout << "c_str1 = " << c_str1 << endl;
cout << "c_str2 = " << c_str2 << endl;
c_str1 = abcdefg
c_str2 = abcdefg
字串修改
不能使用等於=
修改字串,以下語法會編譯錯誤。
1
2
char c_str1[6] = "Hello";
c_str1 = "abc";
使用strcpy修改字串。
1
2
3
4
char c_str1[6] = "Hello";
cout << "Before = " << c_str1 << endl;
strcpy(c_str1,"Dog");
cout << "After = " << c_str1 << endl;
Before = Hello
After = Dog
字元個數拷貝 strncpy
char *strncpy(char *string1, const char *string2, size_t count);
- 參數1:目的字串(拷貝到那裡?)
- 參數2:來源字串(要拷貝的字串)
- 參數3:要拷貝多少個字元
若參數3(拷貝多少個字元)比參數2(來源字串長度)小,拷貝完成後,不會在參數1(目的字串)的結尾加上\0。
1
2
3
4
5
6
7
8
9
10
11
12
13
char c_str4[10];
//拷貝2個字元至c_str4
strncpy(c_str4,"hello",2);
cout << "c_str4[0] = " << c_str4[0] << endl;
cout << "c_str4[1] = " << c_str4[1] << endl;
cout << "c_str4[2] = " << c_str4[2] << endl;
cout << "c_str4[3] = " << c_str4[3] << endl;
cout << "c_str4[4] = " << c_str4[4] << endl;
cout << "c_str4[5] = " << c_str4[5] << endl;
cout << "c_str4[6] = " << c_str4[6] << endl;
cout << "c_str4[7] = " << c_str4[7] << endl;
cout << "c_str4[8] = " << c_str4[8] << endl;
cout << "c_str4[9] = " << c_str4[9] << endl;
以下XCode可以正常執行,會在第2個字元以後補上\0(也就是ascii code = 0,也稱 null character)
c_str4[0] = h
c_str4[1] = e
c_str4[2] =
c_str4[3] =
VS Code執行時,不會在第2個字元以後自動補\0(也就是ascii code = 0,也稱 null character)
c_str4[0] = h
c_str4[1] = e
c_str4[2] = &
c_str4[3] = x00
c_str4[4] = x00
c_str4[5] = x00
c_str4[6] = x00
c_str4[7] = x00
c_str4[8] = x00
c_str4[9] = x00
若一開始把字串的記憶體位址的值全設為ascii code 0,就不會出現上述問題。
1
2
char c_str4[10] = {0};
strncpy(c_str4,"hello",2);
字串長度 strlen
strlen()是計算字串中有幾個字元,不包含字串結尾\0。
sizeof()是計算字串變數全部記憶體大小。
1
2
3
4
5
6
int main() {
char c_str4[10] = "hello!";
cout << "c_str4 size:" << sizeof(c_str4) << endl;
cout << "c_str4長度:" << strlen(c_str4) << endl;
return 0;
}
c_str4 size:10
c_str4長度:6
字串連接 strcat
1
2
3
4
5
6
7
char c_str1[6] = {'h','e','l','\0'};
//[]可為空
char c_str2[] = {'h','e','l','l','o','\0'};
char c_str3[10];
char c_str4[20] = {'t','e'};
strcpy(c_str3, c_str1);
cout << "c_str3 + c_str4 = " << strcat(c_str3,c_str4) << endl;
執行結果
c_str3 + c_str4 = helte
字串比較 strcmp
二個字串,字元逐字元比較ascii code,直到比完或分出大小為止。
strcmp(s1,s2)
s1==s2傳回0
1
2
3
4
5
6
int main() {
char* s1 = "abc";
char* s2 = "abc";
cout << strcmp(s1,s2) << endl;
return 0;
}
0
s1>s2傳回正數ascii code
1
2
3
4
5
6
int main() {
char* s1 = "abc";
char* s2 = "ab";
cout << strcmp(s1,s2) << endl;
return 0;
}
99
s1<s2傳回負數ascii code
1
2
3
4
5
6
int main() {
char* s1 = "ab";
char* s2 = "abc";
cout << strcmp(s1,s2) << endl;
return 0;
}
-99
二維陣列字串
參考
印出禮拜一至禮拜天的英文字母
以下的例子是建立二維的字串,總共有7個字串,每個字串最大長度為10,Wednesday是最長字串,長度為9,加上\0就等於10。
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;
const int DAYS = 7; //字串數,7個字串
const int MAX = 10; // 每個字串最大長度,包含\0
int main() {
char str[DAYS][MAX] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
for (int i = 0; i < DAYS; i++) {
//印出字串
cout << str[i] << endl;
}
return 0;
}
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
判斷數字,印出月份英文
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//12個月
const int MAX_MONTH = 12;
//最長字母September
//9個字元+\0
const int MAX = 10;
int main() {
char mon_arr[MAX_MONTH][MAX] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
int month;
cout << "請輸入數字月份(1~12):";
cin >> month;
//陣列索引介於0..11,所以要把month-1
cout << mon_arr[month-1] << endl;
return 0;
}
請輸入數字月份(1~12):12
December