声明:本文系原创,转载请注明出处。
1. 函数原型
1)gets()函数
char * gets ( char * str );
说明:
从 stdin 读入 str
所指向的字符数组,直到发现换行符或出现文件尾。在读入数组的最后一个字符后立即写入空字符。换行符被舍弃,但不会存储于缓冲区中。
注意:
gets()
函数不进行边界检查,从而此函数对缓冲区溢出攻击极度脆弱。无法安全使用它(除非程序运行的环境限定能出现在stdin
上的内容)。因此gets() 函数在 C99 的第三次勘误中被弃用,而在 C11 标准发布时被移除。推荐的替代品是 fgets() 和gets_s()
。绝对不要用
gets()
。
2)fgets()函数
char *fgets( char *str, int count, FILE *stream ); //(C99 前) char *fgets( char *restrict str, int count, FILE *restrict stream ); //(C99 起)
说明:
从给定文件流读取最多 count - 1 个字符并将它们存储于 str
所指向的字符数组。若文件尾出现或发现换行符则终止分析,后一情况下 str
将包含一个换行符。若无错误发生,则紧随写入到 str
的最后一个字符后写入空字符。
若 count
小于 1 则行为未定义。
注意:
POSIX 附带要求,若 fgets 遇到异于文件尾条件的失败则设置 errno 。
尽管标准规定在 count==1 的情况有歧义,通常实现不读入字符,存储零于 str[0] ,并报告成功(返回
str
)。
3)gets_s()函数
char *gets_s( char *str, rsize_t n );
说明:
从 stdin 读取字符直到发现换行符或出现文件尾。至多写入 n-1 个字符到 str
所指向的数组,并始终写入空终止字符(除非 str
是空指针)。若发现换行符,则忽略它并且不将它计入写入缓冲区的字符数。
gets_s()函数在运行时检测下列错误,并调用当前安装的制约处理函数:
-
n
为零n
大于 RSIZE_MAXstr
是空指针- 在存储 n-1 个字符到缓冲区后没有遇到换行符或文件尾。
在上述异常的任何情况下,gets_s
首先结束读取并忽略来自 stdin 的字符,直到换行符、文件尾条件,或在调用制约处理前的读取错误。
注意:
同所有边界检查函数,
gets_s
仅若实现定义了 __STDC_LIB_EXT1__ ,且用户在包含<stdio.h>
前定义 __STDC_WANT_LIB_EXT1__ 为整数常量 1 才保证可用。(在我的系统上,gets_s函数不可用,因此推荐总是使用fgets()函数来读取字符串)
2. fgets()与gets()比较
1)gets()函数示例:
#include <stdio.h> int main(){ char str[20]; printf("input:\n"); gets(str); char ch = getchar(); printf("\noutput:\n"); printf("str = %s,getchar() = %c\n",str,ch); return 0; }
输出如下:
2)fgets函数示例:
#include <stdio.h> int main(){ char str[20]; printf("input:\n"); fgets(str,20,stdin); char ch = getchar(); printf("\noutput:\n"); printf("str = %s,getchar() = %c\n",str,ch); return 0; }
输出如下:
3)fgets()和gets()的区别:
- fgets()函数的第2个参数指明了读入字符的最大数量。如果该参数的值是n,那么fgets()将读入n-1个字符,或者读到遇到第一个换行符为止;而gets()函数不进行边界检查。
- 如果fgets()读到一个换行符,会把它存储在字符串中(即以 "\n\0" 结尾)。这点与gets()不同,gets()会丢弃换行符(即以 \'\0\' 结尾)。
- fgets()读入的空字符串存储表示为"\n\0" ,gets()读入的空字符串为"\0" 。
- fgets()函数的第三个参数指明要读入的文件。如果读入从键盘输入的数据,则以stdin(标准输入)作为参数,该标识定义在stdio.h中。
- 因为fgets()函数把换行符放在字符串的末尾(假设输入行不溢出),通常要与fputs()函数(与puts()类似)配对使用,除非该函数不在字符串末尾添加换行符。fputs()函数的第2个参数指明它要写入的文件,如果要显示在计算机显示器上,应使用stdout(标准输出)作为该参数。
参考资料:
- https://zh.cppreference.com/w/c/io/gets
- https://zh.cppreference.com/w/c/io/fgets
- https://www.cnblogs.com/aexin/p/3908003.html
- https://blog.csdn.net/hgj125073/article/details/8282883
- https://blog.csdn.net/libing403/article/details/73012280