C 語言無內建字符串類型,以**以空字符 \0 結尾的字符數組**模擬。本文系統梳理字符串字面量存儲、變量聲明初始化、數組與指針差異、輸入輸出函數選型與安全實踐。
n+1 字節 (n 為可見字符數),末尾補 \0char *p = "abc"; 使 p 指向字面量首地址,**非拷貝**p[0] = 'X'; → 未定義行為 (段錯誤/總線錯誤)#define STR_LEN 80 char str[STR_LEN + 1]; // 預留 \0 位置 char date1[8] = "June 14"; // 精確容納 7 字符 + \0 char date2[9] = "June 14"; // 餘下自動填 0 char date3[] = "June 14"; // 編譯器自動計長度 (8)
| 特性 | char arr[] = "text" | char *ptr = "text" |
|---|---|---|
| 存儲位置 | 棧/數據段 (可寫) | 指針在棧,指向只讀段 |
| 可修改性 | ✅ 任意修改元素 | ❌ 修改觸發 UB |
| 指針屬性 | 數組名,常量指針 (不可改指向) | 變量,可重新指向其他字符串 |
sizeof | 數組總字節數 (含 \0) | 指針大小 (4/8 字節) |
需可修改字符串 → 必須用數組。指針變量需先指向有效數組:char buf[100], *p = buf;
printf("%s", str); 通用,支持精度 %.6s 限制長度puts(str); 簡單,**自動換行**,無格式化開銷| 函數 | 行為 | 風險 | 建議 |
|---|---|---|---|
scanf("%s", buf) | 跳過空白,讀至空白,**無長度限制** | 💥 緩衝區溢出 | ❌ 禁用 |
gets(buf) | 讀整行 (含空格),**無長度限制** | 💥💥 溢出溫床,C11 已移除 | ❌❌ 絕對禁用 |
fgets(buf, n, stdin) | 讀至換行或 n-1 字符,**保留 \n** | 需手動去 \n | ✅ 推薦 |
自寫 read_line() | 逐字符 getchar() 至 \n,自動截斷補 \0 | 完全可控 | ✅ 教學/特殊需求 |