---
# System prepended metadata

title: C Language / Characters and Strings
tags: [C Language]

---

# 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（呱呱）***