Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

C 語言 fgets/gets 與 fputs/puts 差異陷阱全解析

編輯:Linux 教學

前言

標準庫提供四個行導向 I/O 函數:fgets/gets(輸入)、fputs/puts(輸出)。它們對換行符 '\n' 處理方式不同,混用極易導致輸出多行或少行。本文以四組實測程式碼,徹底釐清行為差異,給出最佳實踐建議。

一、核心差異速查表

函數讀取/寫入 '\n'緩衝區長度檢查流向
fgets(buf, n, fp)保留 '\n'(若空間足夠)是(n-1 字元)任意 FILE*
gets(buf)捨棄 '\n',不存入緩衝區否(極危險)僅 stdin
fputs(buf, fp)原樣輸出,不增刪 '\n'N/A任意 FILE*
puts(buf)補充 一個 '\n' 到 stdoutN/A僅 stdout

二、四種組合實測(輸入 "abcde\n")

1. fgets + fputs ✅ 完美還原

while (fgets(buf, SIZE, stdin)) fputs(buf, stdout);
  • 讀入:"abcde\n\0"
  • 輸出:"abcde\n" → 換行正確

2. gets + puts ✅ 互補正常

while (gets(buf)) puts(buf);
  • 讀入:"abcde\0"(吃掉 '\n')
  • puts 輸出 "abcde" 並自動加 '\n' → 換行正確

3. gets + fputs ❌ 少一行

while (gets(buf)) fputs(buf, stdout);
  • 讀入:"abcde\0"(無 '\n')
  • fputs 原樣輸出 "abcde" → 下一行輸入接在同一行

4. fgets + puts ❌ 多一行

while (fgets(buf, SIZE, stdin)) puts(buf);
  • 讀入:"abcde\n\0"(含 '\n')
  • puts 輸出 "abcde\n" 並再加 '\n' → 空一行

三、gets 為何被棄用(C11 移除)?

  • 緩衝區溢位:無長度參數,輸入超過 buf 大小直接覆蓋棧/堆 → 安全漏洞根源。
  • 僅限 stdin:通用性差。
  • 替代方案:fgets(buf, sizeof(buf), stdin) + 手動去尾部 '\n'。

四、最佳實踐建議

  1. 統一使用 fgets / fputs:安全、通用、行為可預期(保留原始換行)。
  2. 若需去除輸入尾部 '\n':buf[strcspn(buf, "\n")] = '\0';
  3. 若需輸出時補行:fputs(buf, stdout); fputc('\n', stdout); 明確可控。
  4. 嚴禁混用 gets/puts 與 fgets/fputs,除非極度確定換行語意。

總結

fgets 留 '\n'、gets 吃 '\n';fputs 原樣、puts 加 '\n'。fgets/fputs 組合最安全、最正交,牢記此對應關係,告別換行亂碼與緩衝區溢位噩夢。

Copyright © Windows教程網 All Rights Reserved