---
###### tags: `sprout`
---
# 字元、字串(C-style)
*slide: https://hackmd.io/@r5gr22SqQZOKqVlTHWYDPg/HJdALJME8*
*2020/03/21 丁緒慈*
---
## 字元
*什麼是字元*
----
字元包含了
- 數字:0123456789
- 大寫英文字母:ABCDEFG...
- 小寫英文字母:abcdefg...
- 符號:#$%&()*+,-./:;<=>?@...
**但不只這些!**
----
- 特殊字元,例如:
- 換行 \n
- tab \t
----
### 宣告一個字元(character)
```cpp
//宣告
char c;
//給值
c = 'a';
//初始化
char ch = 'a';
```
----
### 輸入輸出-1
```cpp
char c;
cin>>c;
cout<<c;
```
----
### 輸入輸出-2
怎麼輸出反斜線和引號
```cpp
cout<<'\'; //?
cout<<'''; //?
```
```shell
error: missing terminating ' character
```
----
用反斜線輸出特殊符號
```cpp
cout<<'\\'; //output: \
cout<<'\''; //output: '
```
----
### 電腦如何表達字元呢
電腦只有0跟1欸
----
#### ASCII編碼

----
example 1:
```cpp
int c = 'a';
cout<<c<<endl; //output: 97
int c = 97;
cout<<char(c)<<endl; //output: a
```
example 2:
```cpp
char c = 97;
cout<<c<<endl; //output: a
char c = 'a';
cout<<int(c)<<endl; //output: 97
```
----
小練習
用迴圈印出a~z (ascii code 97~122)
(X) cout<<"abcdefghijklmnopqrstuvwxyz"
----
```cpp
#include<iostream>
using namespace std;
int main()
{
for(int i = 97; i<=122; ++i)
cout<<char(i);
return 0;
}
```
```cpp
#include<iostream>
using namespace std;
int main()
{
for(char c = 'a'; c <= 'z'; ++c)
cout<<c;
return 0;
}
```
----
#### 既然字元是透過數字表達 字元與數字間可以運算嗎
例如:'p'+1, 'q'-2
----
可以
```cpp
char c = 'a';
cout<<c<<endl;
c+=2;
cout<<c<<endl;
c-=1
cout<<c<<endl;
```
----
```cpp
if('b'=='a'+1)
cout<<"yes\n";
if(98=='a'+1)
cout<<"correct\n";
```
----
#### 那字元與字元間呢?
例如:'Q'-'P'
----
也可以
```cpp
char c = 'z';
cout<<c-'a'<<endl;
cout<<'c'+'A'-'b'-'B'<<endl;
```
----
#### 還可以比大小
- 'a'<'b' (97<98)
- 'A'<'a' (65<97)
- '0'<'9' (48<57)
----
### 小練習
如果輸入大寫,就輸出小寫
如果輸入小寫,就輸出大寫
----
#### ~~--解法-1--~~
```cpp
if(c=='A') cout<<'a';
else if(c=='B') cout<<'b';
else if(c=='C') cout<<'c';
...
```
----
#### 解法-2: 觀察ASCII碼
| 大寫字元 | ASCII | 小寫字元 | ASCII |
| -------- | ----- | -------- | ----- |
| A | 65 | a | 97 |
| B | 66 | b | 98 |
| C | 67 | c | 99 |
| ... | ... | ... | ... |
| Z | 90 | z | 122 |
----
```cpp
char c;
cin>>c;
if(65<=c && c<=90)
{
c+=32;
cout<<c;
}
else if(97<=c && c<=122)
{
c-=32;
cout<<c;
}
```
----
#### 解法-3: 字元運算
```cpp
char c;
cin>>c;
if('A'<=c && c<='Z')
{
c+='a'-'A';
cout<<c;
}
else if('a'<=c && c<='z')
{
c-='a'-'A';
cout<<c;
}
```
---
## 字串(C-style)
----
一個字元一個字元的說話很累耶
```cpp
char s = 's', p = 'p', r = 'r', o = 'o', u = 'u', t = 't';
cout<<s<<p<<r<<o<<u<<t;
```
----
把多個字元串在一起=>字串
怎麼做?
----
### 字元陣列
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|:--- |:--- |:--- |:--- |:--- |:--- |:---- |
| 's' | 'p' | 'r' | 'o' | 'u' | 't' | '\0' |
----
| 0 | 1 | 2 | 3 | 4 | 5 | 6 |
|:--- |:--- |:--- |:--- |:--- |:--- |:---- |
| 's' | 'p' | 'r' | 'o' | 'u' | 't' | <span class="y">'\0'</span> |
- '\0'就像是字串的句點
- 在輸出字元陣列時,會輸出到'\0'為止
- 也就是說,'\0'後的字元不會被輸出
----
會輸出甚麼?
```cpp
char str[100] = "HelloWorld";
str[5] = '\0';
cout<<str;
```
----
|0|1|2|3|4|5|6|7|8|9|10|
|:-|:-|:-|:-|:-|:-|:-|:-|:-|:-|:-|
|<span class="y">'H'</span>|<span class="y">'e'</span>|<span class="y">'l'</span>|<span class="y">'l'</span>|<span class="y">'o'</span>|<span class="y">'W'</span>|<span class="y">'o'</span>|<span class="y">'r'</span>|<span class="y">'l'</span>|<span class="y">'d'</span>|'\0'|
|0|1|2|3|4|5|6|7|8|9|10|
|:-|:-|:-|:-|:-|:-|:-|:-|:-|:-|:-|
|<span class="y">'H'</span>|<span class="y">'e'</span>|<span class="y">'l'</span>|<span class="y">'l'</span>|<span class="y">'o'</span>|'\0'|'o'|'r'|'l'|'d'|'\0'|
<style>
.y {
color: yellow;
}
</style>
----
### 宣告
```cpp
char str1[100] = "Hello";
char str2[] = "World";
char str3[100] = {'c', 'p', 'p', '\0'};
```
----
### 輸入輸出
```cpp
char str[10];
cin>>str; //至多輸入?個字元
cout<<str;
```
----
### 大家來找碴
```cpp
char a[6] = "abcde";
char b[6];
b = a;
cout<<b<<"\n";
```
```shell
error: invalid array assignment
```
----
你會這樣做嗎
```cpp
int a[6] = {1, 2, 3, 4, 5, 6};
int b[6];
b = a;
cout<<b<<"\n";
```
不會,所以字元陣列也不能這樣操作
----
```cpp
char a[6] = "abcde";
char b[6];
for(int i = 0; i<6; ++i)
b[i] = a[i];
cout<<b<<"\n";
```
----
### 課堂練習
[217-凱薩密碼](https://neoj.sprout.tw/problem/217/)
----
| 輸入 | 輸出 || 輸入 | 輸出 |
| :----: | :----: |-| :----: | :----: |
| a | d || x | a |
| b | e || y | b |
| c | f || z | c |
輸入皆為小寫字母,位移3再輸出
----
#### 解法
```cpp
#include<iostream>
using namespace std;
int main()
{
char str[600];
cin>>str;
for(int i = 0; str[i]!='\0'; ++i)
//TODO
cout<<str<<"\n";
}
```
----
### 字串陣列
```cpp
char arr[3][4] = {"abc", "def", "ghi"};
//3個字串
//每個字串包含'\0'最多4字元
```
| | 0 | 1 | 2 | 3 |
| --- | --- | --- | --- | ---- |
| 0 | 'a' | 'b' | 'c' | '\0' |
| 1 | 'd' | 'e' | 'f' | '\0' |
| 2 | 'g' | 'h' | 'i' | '\0' |
----
#### 輸入輸出
```cpp
char arr[3][10]
for(int i = 0; i<3; ++i)
cin>>arr[i];
for(int i = 0; i<3; ++i)
cout<<arr[i]<<'\n';
```
{"metaMigratedAt":"2023-06-15T04:38:33.259Z","metaMigratedFrom":"Content","title":"字元、字串(C-style)","breaks":true,"contributors":"[{\"id\":\"af982bdb-64aa-4193-8aa9-59531d66033e\",\"add\":8380,\"del\":3230}]"}