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

C/C++ 讀取含空白字元字串的標準做法:getline 與 getline 完全指南

     編輯:關於C

問題背景

cin >> str 或 scanf("%s") 遇到空白(空格、Tab、換行)即停止,無法讀取完整行或含空格的字串。正確做法是使用行導向輸入函數。

C++ 風格:std::getline

#include 
#include 

int main() {
    std::string line;
    std::cout << "請輸入一行文字(可含空格):";
    std::getline(std::cin, line); // 讀取整行,含前導/尾隨空格,不含換行符
    std::cout << "您輸入:" << line << '\n';
    return 0;
}
  • 自動處理記憶體分配,無緩衝區溢位風險。
  • 可指定自定分隔符:std::getline(cin, str, '|')。
  • 若前一次用 cin >> n 留下換行符,需先 cin.ignore(std::numeric_limits::max(), '\n'); 清除。

C 風格:fgets / getline (POSIX)

1. fgets(標準 C,普遍可用)

#include 
#include 

#define MAX_LEN 1024

int main() {
    char buf[MAX_LEN];
    printf("輸入:");
    if (fgets(buf, MAX_LEN, stdin)) {
        // 移除尾部換行符(若有)
        buf[strcspn(buf, "\n")] = '\0';
        printf("內容:%s\n", buf);
    }
    return 0;
}
  • 保留換行符(若緩衝區足夠大),需手動移除。
  • 若輸入超過 MAX_LEN-1,剩餘字元留在 stdin,下次讀取會繼續讀取殘留部分。

2. getline / getdelim(POSIX.1-2008,Linux/macOS/BSD)

#include 
#include 

int main() {
    char *line = NULL;
    size_t len = 0;
    ssize_t nread;

    printf("輸入(Ctrl+D 結束):\n");
    while ((nread = getline(&line, &len, stdin)) != -1) {
        if (nread > 0 && line[nread-1] == '\n') line[nread-1] = '\0';
        printf("長度 %zd:%s\n", nread, line);
    }
    free(line); // 必須釋放
    return 0;
}
  • 自動動態擴充緩衝區,無長度限制。
  • 返回讀取字元數(含換行符),EOF 返回 -1。
  • 編譯需 _GNU_SOURCE 或 -D_POSIX_C_SOURCE=200809L。

常見陷阱與對策

現象原因解決
第一次 getline 讀到空字串前一次 scanf/cin>> 留下 '\n'先呼叫 getchar() / cin.ignore() 吃掉換行
輸入超長被截斷fgets 緩衝區固定大小改用 getline (POSIX) 或 C++ std::getline
Windows 下 getline 讀到 '\r'CRLF 換行手動移除尾部 '\r':if (line[len-1]=='\r') line[--len]=0;

最佳實務建議

  1. C++ 專案:統一使用 std::getline + std::string,搭配 std::stringstream 做後續解析。
  2. C 專案:優先用 POSIX getline(動態記憶體、無長度限制),不支援平台時退回 fgets + 循環讀取拼接。
  3. 交互式程式:每次讀取前印提示符,檢查 EOF (Ctrl+D / Ctrl+Z) 優雅退出。
  4. 解析欄位:讀完整行後用 strtok_r、sscanf、或 C++ std::istringstream 分割,避免直接用 scanf 格式字串處理複雜輸入。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved