# 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(呱呱)***