一、C 語言裏的字符串截取(重點:沒有內置函數)

C 標準庫沒有直接的“substring”函數,截取只能靠 指針 + 拷貝手動改 '\0'


1️⃣ 指針偏移(不拷貝,最快)

char str[] = "HelloWorld";

char* sub = str + 5;
printf("%s\n", sub);   // World
  • 不創建新字符串
  • 只是“從某個位置開始看”
  • 原字符串不能釋放
  • 修改 sub 會影響 str

只能從某個位置截到結尾,不能控制長度


2️⃣ strncpy 截取指定長度(常用)

char src[] = "HelloWorld";
char dst[6] = {0};

strncpy(dst, src + 5, 5);
dst[5] = '\0';

printf("%s\n", dst);  // World
  • strncpy 不會自動補 \0
  • 一定要手動結尾

3️⃣ memcpy + '\0'(更推薦)

char src[] = "HelloWorld";
char dst[6];

memcpy(dst, src + 5, 5);
dst[5] = '\0';

printf("%s\n", dst);

✅ 比 strncpy 更直觀、少坑 在底層開發裏更常見


4️⃣ 直接“截斷”原字符串(慎用)

char str[] = "HelloWorld";
str[5] = '\0';

printf("%s\n", str);  // Hello

📌 原理:字符串就是遇到 '\0' 就結束 ,會永久修改原字符串


二、C 的大小寫轉換(ctype.h)

👉 標準頭文件:

#include <ctype.h>

1️⃣ 單字符轉換

char c = 'a';

c = toupper(c);  // 'A'
c = tolower(c);  // 'a'

只對 ASCII 字母 有效 , 返回值是 int,但可直接賦給 char


2️⃣ 整個字符串轉大寫

void to_upper(char* s) {
    while (*s) {
        *s = toupper((unsigned char)*s);
        s++;
    }
}
char str[] = "Hello123";
to_upper(str);
printf("%s\n", str); // HELLO123

必須轉成 unsigned char 這是老 C 的經典坑(負值 UB)


3️⃣ 整個字符串轉小寫

void to_lower(char* s) {
    while (*s) {
        *s = tolower((unsigned char)*s);
        s++;
    }
}

三、常見錯誤總結

❌ 1. 忘記 \0

char buf[5];
memcpy(buf, "Hello", 5);
printf("%s\n", buf);   // ❌ 未定義行為

✔ 正確:

buf[4] = '\0';

❌ 2. 修改字符串常量

char* s = "hello";
s[0] = 'H';   // ❌ 崩潰

✔ 正確:

char s[] = "hello";

❌ 3. toupper 不轉 unsigned char

toupper(*p);   // ❌ 非 ASCII 字符可能炸

✔ 正確:

toupper((unsigned char)*p);

四、最後

  • C 沒有 substring
  • 截取 = 指針偏移 or memcpy
  • 字符串結束靠 '\0'
  • 大小寫用 toupper / tolower
  • 字符一定要 (unsigned char)