首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言讀取含空格字符串的三種方法對比與最佳實踐

     編輯:關於C語言

問題背景

scanf("%s", str) 遇到空白字符 (空格、制表符、換行) 即停止,無法讀取含空格的字符串。

方法一:掃描集 %[^\n] (推薦)


char str[100];
scanf("%[^\n]", str);  // 讀到換行符停止
getchar();  // 關鍵:吸收殘留在緩衝區的 \n
  • 優點:標準 C、無需額外庫、可控制匹配字符集
  • 缺點:需手動吸收換行符、緩衝區溢出風險
  • 安全版:scanf("%99[^\n]", str) 限制寬度

方法二:fgets (最安全、推薦生產環境)


char str[100];
fgets(str, sizeof(str), stdin);
// 移除末尾換行符 (若有)
size_t len = strlen(str);
if (len > 0 && str[len-1] == '\n') str[len-1] = '\0';
  • 優點:自動限制長度防溢出、保留換行符可選擇性移除、無殘留字符問題
  • 缺點:換行符需手動處理、不如 scanf 靈活解析格式化輸入

方法三:getchar 循環 (教學用、底層理解)


char str[100];
int i = 0, ch;
while ((ch = getchar()) != '\n' && ch != EOF && i < 99)
    str[i++] = ch;
str[i] = '\0';
  • 優點:完全可控、理解輸入流機制
  • 缺點:代碼冗長、易出錯、性能較差

三種方法對比表

維度scanf %[^\n]fgetsgetchar 循環
安全性需手動限寬✅ 自動限長需手動限長
換行符處理殘留需吸收保留在字符串中不包含換行符
靈活性高 (掃描集)低 (整行讀取)極高 (逐字符)
推薦場景簡單交互、格式解析前生產代碼、文件讀取教學、特殊解析

常見陷阱與解決方案

1. scanf 後接 fgets 讀空行
scanf("%d", &n); fgets(s, 100, stdin); → fgets 讀到殘留 \n。
解決:scanf 後加 getchar() 或用 scanf(" %[^\n]", s) (前導空格吃空白)。
2. gets 已棄用且極度危險
gets(str); 無長度檢查,必導致緩衝區溢出漏洞。
禁用:C11 標準已移除,編譯器會報警。永遠用 fgets 替代。
3. 掃描集不匹配不消耗輸入
scanf("%[0-9]", s); 輸入 "abc" → 返回 0,'a' 留在緩衝區。
解決:檢查返回值,失敗時用 while(getchar()!='\n'); 清行。

最佳實踐組合拳


// 讀整數後安全讀行
int n;
char line[1024];
scanf("%d", &n);
getchar();  // 吸收換行
fgets(line, sizeof(line), stdin);  // 讀完整行
line[strcspn(line, "\n")] = '\0';  // 通用去換行

// 或純 scanf 掃描集
scanf("%d", &n);
scanf(" %1023[^\n]", line);  // 前導空格吃空白,限寬 1023

總結

生產代碼首選 fgets:安全、標準、無殘留問題。交互式簡單輸入用 scanf 掃描集:配合寬度限制和前導空格。徹底拒絕 gets。理解輸入流緩衝機制(行緩衝、字符殘留)是避免輸入 Bug 的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved