为什么gets()需要更多的字符

Why gets() takes more character

本文关键字:字符 gets 为什么      更新时间:2023-10-16

这是我的代码

char c[3];
gets(c);
puts(c);

这里字符变量 C 有 3 个索引。但是,如果我键入超过 3 个字母,那么我的代码会打印超过 3 个我键入的字母。但是c怎么可能一次只能存储3个字符。不是吗?

来自gets注释:

该函数不提供任何方法来防止目标数组的缓冲区溢出,给定足够长的输入字符串。

因此,如果stdin恰好有超过 3 个字符,则您的代码只是未定义的行为。这是首选调用的一个很好的理由:

fgets(c, sizeof(c), stdin);

这绝对不会溢出。

欢迎来到缓冲区溢出的奇妙世界。

数组

上没有长度检查,因此代码离开数组的末尾并继续写入相邻内存。这是代码中安全问题的众多原因之一。

gets() 不限制要读取的字符的双节棍,也不关心要在哪里写入它们,它假设目标缓冲区足够大。

你为什么希望它停止阅读?

正因为如此,您应该使用不同的函数来限制要读取的字符数,您需要fgets()

char c[3];
fgets(c, sizeof(c), stdin);
puts(c);

这将没有问题,但请注意,实际上只会读取 2 个字符,因为第 3 个位置是为终止''字节保存的,这使您的数组成为字符串。

你的程序

正在调用未定义的行为,所以你可能会观察到奇怪的结果,或者你的程序可以正常工作,它不依赖于程序本身,而是依赖于其他东西,例如输入,以及其他东西。

你有责任确保缓冲区足够大,以容纳gets()读取的整个字符串(包括终止 null)。如果不这样做,则会发生未定义的行为(这实际上意味着其他内存位置被覆盖)。除非您保证输入字符串的长度,否则通常无法安全地执行此操作。这就是为什么gets在 C99 和 C++11 中被弃用并在 C11 和 C++14 中删除的原因。请考虑改用fgets

gets()实际上并不知道传递给它的内存块有多大。如果您为其提供的字符数超过块大小,则会调用未定义的行为。