首页 > 编程笔记 > C语言笔记

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 的注意事项

使用 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笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。