首页 > 编程笔记 > C语言笔记(精华版)

C语言gets_s函数的用法(非常详细和完整)

C语言 gets_s() 函数用于安全地从标准输入(通常是键盘)读取字符串,它是 gets() 函数的安全替代品。gets() 函数很容易导致缓冲区溢出,而 gets_s() 函数提供了更好的安全性,通过限制可以读取的最大字符数来防止缓冲区溢出。


gets_s() 位于 <stdio.h> 头文件中,它的原型如下:

char *gets_s(char *str, rsize_t n);

参数说明:

 

返回值:如果成功读取字符串,gets_s() 返回 str 指针;如果发生错误或遇到文件结束符 (EOF),则返回 NULL。


gets_s() 函数会在读取 n-1 个字符后自动添加终止空字符\0,确保不会发生缓冲区溢出。如果用户输入的字符数超过了指定的 n-1 个字符,gets_s() 会停止读取,丢弃多余的字符,并在缓冲区末尾添加\0

如果 str 为 NULL,或者 n 为 0,或者 n 大于 RSIZE_MAX,gets_s() 会触发运行时约束处理程序。

下面是一个使用 gets_s() 函数的示例:

#include <stdio.h>

int main() {
    char name[50];
    printf("请输入你的名字: ");
    
    if (gets_s(name, sizeof(name)) != NULL) {
        printf("你好,%s!\n", name);
    } else {
        printf("读取输入时发生错误。\n");
    }
    
    return 0;
}

在这个例子中,我们创建了一个可以存储 50 个字符的数组 name。使用 gets_s() 函数读取用户输入的名字,并将其存储在 name 数组中。sizeof(name) 用于指定可以读取的最大字符数,确保不会超出数组的边界。


运行这段代码,可能会得到如下输出:

请输入你的名字: John Doe
你好,John Doe!

注意:gets_s() 不是标准函数

gets_s() 最早是由微软的 Visual C++ 编译器(Microsoft Visual Studio 内置编译器)支持的,后来,它又被 C11 标准引入。但是请注意,gets_s() 仅仅是被作为可选的扩展功能之一,而不是 C11 标准的核心部分。
 

这意味着,并不是所有遵循 C11 标准的编译器都必须实现 gets_s() 函数,或者通过某些设置才能开启 gets_s() 函数。 所以,如果你考虑跨平台,或者在非 Windows 平台下编程,那么建议使用标准的 fgets() 函数来替代 gets_s()。
 

总之,一般在 Windows 平台下才使用 gets_s() 函数。

对比gets_s()和gets()

gets_s() 函数相比于传统的 gets() 函数有两个优势:


然而,使用 gets_s() 函数时也需要注意一些潜在的问题:


为了更好地控制输入,有时候使用 fgets() 函数可能是更好的选择。fgets() 允许指定输入源(如标准输入 stdin),并且会保留换行符。例如:

#include <stdio.h>
#include <string.h>

int main() {
    char name[50];
    printf("请输入你的名字: ");
    
    if (fgets(name, sizeof(name), stdin) != NULL) {
        // 移除换行符
        name[strcspn(name, "\n")] = 0;
        printf("你好,%s!\n", name);
    } else {
        printf("读取输入时发生错误。\n");
    }
    
    return 0;
}

这个例子使用 fgets() 读取输入,然后使用 strcspn() 函数删除结尾的换行符。这种方法提供了更多的灵活性和控制,特别是在处理可能包含空格的输入时。


总之,gets_s() 函数是一个安全的输入函数,适用于需要从标准输入读取字符串的场景。gets_s() 通过限制输入长度来提高安全性,但在使用时需要注意其特性和潜在的限制。


注意,在某些情况下,考虑使用 fgets() 可能会带来更大的灵活性和控制力。

相关文章