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

C語言 gets 與 puts 函數詳解:行級輸入輸出、安全性與替代方案

     編輯:關於C

函數原型

char *gets(char *str);   // 已棄用,C11 移除\
int puts(const char *str);

gets:危險的行輸入

  • 從 stdin 讀取一行(含空格),遇 \\n 或 EOF 停止。
  • 不檢查緩衝區大小,極易導致緩衝區溢出,是經典安全漏洞根源。
  • 將 \\n 替換為 \\0 存入 str。
  • 成功返回 str,失敗返回 NULL。

puts:簡單的行輸出

  • 向 stdout 輸出字符串 str,自動追加 \\n。
  • 成功返回非負值,失敗返回 EOF。
  • 不輸出字符串結束符 \\0。

頭文件與 C++ 對應

參數均為字符數組 char[],不可直接傳遞 C++ std::string。

安全替代方案

// C11 安全版(可選實現)\
char *gets_s(char *str, rsize_t n);\

// 推薦:fgets 指定最大讀取長度\
char *fgets(char *str, int n, FILE *stream);\
// 讀取最多 n-1 字符,保留 \\n,遇 EOF/\\n 停止\

// C++ 最佳實踐\
#include \
#include \
std::string line;\
std::getline(std::cin, line);  // 自動管理內存,無長度限制\

對比總結表

語言頭文件
C<stdio.h>
C++<cstdio>
特性getsfgetsstd::getline
緩衝區保護無有 (n)自動擴容
保留換行符否 (轉\\0)是否 (丟棄)
標準狀態C11 移除C 標準C++ 標準
推薦程度❌ 禁用✅ C 環境首選✅ C++ 環境首選

典型錯誤代碼與修正

// ❌ 錯誤:指針未分配內存\
char *cp;\
scanf("%s", cp);  // 未初始化指針,野指針寫入\

// ✅ 修正 1:使用數組分配棧內存\
char cp[20];\
scanf("%19s", cp);  // 限制寬度防溢出\

// ✅ 修正 2:動態分配\
char *cp = malloc(20);\
if (cp) { scanf("%19s", cp); free(cp); }\

// ✅ 修正 3:fgets 讀取整行含空格\
char line[100];\
fgets(line, sizeof(line), stdin);

最佳實踐建議

  1. 永不使用 gets,編譯器會警告,靜態分析工具會報錯。
  2. C 環境統一使用 fgets + 去除尾部 \\n 輔助函數。
  3. C++ 環境優先 std::getline + std::string。
  4. scanf("%s") 同樣不安全,必須加寬度限制 %19s 或改用 fgets。

理解 gets 的危險性並掌握安全替代方案,是 C/C++ 開發者必備的安全編碼基礎素養。

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