C语言fgets()和gets()的区别(附带实例)
在C语言中,fgets 和 gets 都是用于从输入流中读取字符串的函数,但它们在安全性和使用方式上存在显著差异。
gets 函数
gets 函数用于从标准输入(通常是键盘)读取一行字符,直到遇到换行符或文件结束符,它的原型如下:
char *gets(char *str);
gets 函数的使用非常简单,例如:
#include <stdio.h> int main() { char str[100]; printf("请输入一个字符串:"); gets(str); printf("你输入的是:%s\n", str); return 0; }
然而,gets 函数存在严重的安全隐患,它不会检查输入的长度,可能导致缓冲区溢出,这是一个常见的安全漏洞。如果用户输入的字符串长度超过了预分配的缓冲区大小,程序可能会崩溃或产生不可预知的行为。
fgets 函数
fgets 函数是一个更安全的替代方案,它不仅可以从标准输入读取,还可以从任何指定的文件流中读取。fgets 的原型如下:
char *fgets(char *str, int n, FILE *stream);
这里,str 是存储读取字符的缓冲区,n 是要读取的最大字符数(包括结尾的空字符),stream 是要读取的文件流。
使用 fgets 的示例:
#include <stdio.h> int main() { char str[100]; printf("请输入一个字符串:"); fgets(str, sizeof(str), stdin); printf("你输入的是:%s", str); return 0; }
fgets 函数会读取 n-1 个字符或直到遇到换行符,无论哪个先发生,它会在字符串末尾添加空字符 '\0',并保留换行符(如果读取到)。
fgets 和 gets 的主要区别
我们可以将 fgets 和 gets 函数的区别总结为以下几点:
- 安全性:fgets 允许指定最大读取字符数,防止缓冲区溢出;gets 没有这种保护机制。
- 灵活性:fgets 可以从任何文件流读取,而 gets 只能从标准输入读取。
- 换行符处理:fgets 保留换行符(如果读取到),而 gets 会丢弃换行符。
- 返回值:两个函数在成功时都返回读取到的字符串的指针,在失败或遇到文件结束时返回 NULL。但 fgets 在只读取到换行符时也会返回成功,而 gets 不会。
fgets 的注意事项
使用 fgets 时,需要注意以下几点:
1) fgets 可能会在字符串中保留换行符,如果不需要,可以手动移除:
#include <stdio.h> #include <string.h> int main() { char str[100]; printf("请输入一个字符串:"); fgets(str, sizeof(str), stdin); // 移除换行符 str[strcspn(str, "\n")] = 0; printf("你输入的是:%s\n", str); return 0; }
2) 如果输入的字符串长度超过了指定的最大长度,fgets 会留下一个未读取的换行符在输入缓冲区中。在连续读取多行时,这可能会导致问题。可以通过清空输入缓冲区来解决:
#include <stdio.h> void clear_input_buffer() { int c; while ((c = getchar()) != '\n' && c != EOF); } int main() { char str[10]; printf("请输入一个字符串:"); fgets(str, sizeof(str), stdin); clear_input_buffer(); // 清空输入缓冲区 printf("你输入的是:%s\n", str); return 0; }
综上所述,fgets 函数是一个更安全、更灵活的输入函数,应该优先使用。虽然 gets 函数使用起来更简单,但由于其安全隐患,在现代 C 编程中应该避免使用。事实上,gets 函数已经在 C11 标准中被正式废弃。作为负责任的程序员,我们应该始终选择更安全的编程方式,以创建更可靠、更健壮的软件。
声明:《C语言系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。