# C Language / Characters and Strings
## 概述
C 標準函式庫中有各種函式用於處理字元、字串、文字行以及記憶體區塊。除此之外,讓我們也再來多討論一些在開發文字編輯器、版面設計軟體、電腦排版系統等文字處理軟體時所使用的技術ㄅ。
- **字元 => char**
- **字串 => string**
- **文字行 => line**
前情提要:我知道統一用中文寫讀起來一定比較舒適,理解上的速度甚至會更快一些,但我怕大家真的讀完就忘了,所以有些地方我還是很機車的用英文表示,希望透過大腦多一層的轉換能讓大家更熟悉這些函式庫,畢竟還是要考試但就真的挺沒意義,平常有用到再查就好。
## 字元和字串ㄉ基礎
- char 是程式的基本構建塊,每個程式都是由一系列字元組成的指令序列。
- 程式中包含的字元常數通常用單引號 `'` 表示,例如 `'z'` 表示字元 `z` 的整數值 (ASCII)。
- string 是一系列被視為單個 char 的序列,可包含字母、數字和各種特殊字元。
- C 的字串常量用雙引號 `"` 表示,並以 null 字元 `'\0'` 結尾。
- string 通過指向第一個 char 的指標來訪問。
- 字串的值是其第一個字元的地址,因此在 C 中,字串本質上是一個指標。
## `<ctype.h>` 字元處理函式庫
`<ctype.h>` 包含了一些用於測試和操作字元資料的函式,例如判斷字元是否為數字、字母等。以下是一些常用的字元處理函式:
- `isalnum`、`isalpha`、`isdigit`、`islower`、`isprint`、`ispunct`、`isspace`、`isupper` 等用於檢測字元類型的函式。
- `tolower`、`toupper` 用於將字元轉換為小寫或大寫。
```c=
#include <ctype.h>
#include <stdio.h>
int main() {
char ch = 'A';
printf("%c is %salphabet.\n", ch, isalpha(ch) ? "" : "not ");
printf("%c converted to lower is %c.\n", ch, tolower(ch));
return 0;
}
```
**Output:**
:::success
**A is alphabet.
A converted to lower is a.**
:::
## `<stdlib.h>` 字串轉換函式
`<stdlib.h>` 包含了一些將字串轉換為整數或浮點數的函式:
- `strtod` 將字串轉換為 `double` 類型。
- `strtol` 將字串轉換為 `long int` 類型。
- `strtoul` 將字串轉換為 `unsigned long int` 類型。
```c=
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "3.14159";
char *endptr;
double d = strtod(str, &endptr);
printf("string = %s, double = %f\n", str, d);
return 0;
}
```
**Output:**
:::success
**string = 3.14159, double = 3.141590**
:::
## `<stdio.h>` 字元和字串輸入 / 輸出函式
`<stdio.h>` 包含了一些用於處理字元和字串輸入 / 輸出的函式:
- `fgets` 從輸入流中讀取一行文字到 char[ ] 中。
- `putchar` 輸出單個 char。
- `getchar` 從輸入流中讀取單個 char。
- `puts` 輸出 string。
- `sprintf` 將格式化資料輸出到字元陣列中。
- `sscanf` 從字元陣列中讀取格式化資料。
```c=
#include <stdio.h>
int main() {
char str[100];
printf("Enter a string: ");
fgets(str, sizeof(str), stdin);
printf("You entered: %s", str);
return 0;
}
```
## `<string.h>` 字串處理函式庫
`<string.h>` 提供了許多用於操作 string 的實用函式,例如複製、連接、比較、搜索、分割以及計算長度等。
### 字串複製和連接
- `strcpy` 將一個 string 複製到另一個 char[ ] 中。
- `strncpy` 將指定數量的字元從一個字串複製到另一個字元陣列中。
- `strcat` 將一個字串附加到另一個字串的末尾。
- `strncat` 將指定數量的字元從一個字串附加到另一個字串的末尾。
```c
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
strcat(str1, str2);
printf("%s\n", str1);
return 0;
}
```
**Output:**
:::success
**HelloWorld**
:::
### 字串比較
- `strcmp` 比較兩個 string。
- `strncmp` 比較兩個字串的指定數量字元。
```c=
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Apple";
char str2[] = "Orange";
if (strcmp(str1, str2) < 0) {
printf("%s comes before %s\n", str1, str2);
} else if (strcmp(str1, str2) > 0) {
printf("%s comes after %s\n", str1, str2);
} else {
printf("%s is the same as %s\n", str1, str2);
}
return 0;
}
```
**Output:**
:::success
**Apple comes before Orange**
:::
### 字元和子字串搜索
- `strchr` 在字串中尋找第一個出現的指定字元。
- `strrchr` 在字串中尋找最後一個出現的指定字元。
- `strstr` 在字串中尋找第一個出現的子字串。
- `strtok` 將字串分割為一系列標記。
```c=
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *token = strtok(str, " ,");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, " ,");
}
return 0;
}
```
**Output:**
:::success
**Hello
World!**
:::
### 記憶體操作
- `memcpy` 從一個記憶體區塊複製字元到另一個記憶體區塊。
- `memmove` 從一個記憶體區塊移動字元到另一個記憶體區塊,可處理重疊的情況。
- `memcmp` 比較兩個記憶體區塊。
- `memchr` 在一個記憶體區塊中尋找第一個出現的字元。
- `memset` 將一個記憶體區塊設置為指定的字元值。
```c=
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[20];
memcpy(dest, src, sizeof(src));
printf("%s\n", dest);
return 0;
}
```
### 其他函式
- `strlen` 計算字串長度。
## 呱呱精選範例教學
我寫ㄉ範例捏,所以一定是精選(同學請不要那麼自戀
### **範例一:檢測字元類型並轉換大小寫**
```c=
#include <ctype.h>
#include <stdio.h>
int main() {
char ch = 'a';
printf("Character entered: %c\n", ch);
printf("Is alphanumeric: %d\n", isalnum(ch)); //檢測是否為字母或數字
printf("Is alphabetic: %d\n", isalpha(ch)); //檢測是否為字母
printf("Is digit: %d\n", isdigit(ch)); //檢測是否為數字
printf("To lowercase: %c\n", tolower(ch)); //將字元轉換為小寫
printf("To uppercase: %c\n", toupper(ch)); //將字元轉換為大寫
return 0;
}
```
**Output:**
:::success
**Character entered: a
Is alphanumeric: 2
Is alphabetic: 2
Is digit: 0
To lowercase: a
To uppercase: A**
:::
### **範例二:字串連接**
```c=
#include <stdio.h>
#include <string.h>
int main() {
char str1[100], str2[100];
printf("Enter the first string: ");
fgets(str1, sizeof(str1), stdin);
printf("Enter the second string: ");
fgets(str2, sizeof(str2), stdin);
char result[200];
strcpy(result, str1); //複製字串
strcat(result, str2); //連接字串
printf("Concatenated string: %s", result);
return 0;
}
```
### **範例三:字串反轉**
```c=
#include <stdio.h>
#include <string.h>
void reverseString(char *str) {
int len = strlen(str); //獲取字串長度
char temp;
for (int i = 0; i < len / 2; i++) {
temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
}
int main() {
char str[100];
printf("Enter a string: ");
fgets(str, sizeof(str), stdin); //讀取字串輸入
reverseString(str);
printf("Reversed string: %s", str);
return 0;
}
```
### **範例四:統計字元出現次數**
```c=
#include <stdio.h>
#include <string.h>
int countChar(char *str, char ch) {
int count = 0;
for (int i = 0; str[i] != '\0'; i++) { //遍歷字串
if (str[i] == ch) {
count++;
}
}
return count;
}
int main() {
char str[100];
char ch;
printf("Enter a string: ");
fgets(str, sizeof(str), stdin); //讀取字串輸入
printf("Enter a character: ");
scanf("%c", &ch);
int count = countChar(str, ch);
printf("Character '%c' appears %d times in the string.\n", ch, count);
return 0;
}
```
### **範例五:分割電話號碼**
```c=
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char phone[20];
char *token, *delim = "()-";
int areaCode;
long phoneNumber;
printf("Enter a phone number in the format (xxx) xxx-xxxx: ");
fgets(phone, sizeof(phone), stdin); //讀取電話號碼輸入
// 提取區碼
token = strtok(phone, delim); //分割字串
areaCode = atoi(token); //將字串轉換為整數
// 提取前三碼
token = strtok(NULL, delim); //分割字串
char prefix[4];
strcpy(prefix, token); //複製字串
// 提取後四碼
token = strtok(NULL, delim); //分割字串
char suffix[5];
strcpy(suffix, token); //複製字串
// 合併前三碼和後四碼
char phoneStr[9];
strcpy(phoneStr, prefix); //複製字串
strcat(phoneStr, suffix); //連接字串
phoneNumber = atol(phoneStr); //將字串轉換為長整數
printf("Area Code: %d\n", areaCode);
printf("Phone Number: %ld\n", phoneNumber);
return 0;
}
```
---
*註: 部分內容截自於網路,此筆記非完全原創。*
***Latest Updated On:2024.05.29,
published with the of LICENSE of WTFPL
Author:Qaron(呱呱)***