为什么gets()需要更多的角色

时间:2015-01-27 22:30:06

标签: c++ c

这是我的代码

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

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

5 个答案:

答案 0 :(得分:5)

来自gets的说明:

  

在给定足够长的输入字符串的情况下,该函数无法防止目标数组的缓冲区溢出。

因此,如果stdin碰巧有超过3个字符,那么您的代码就是未定义的行为。这是一个更喜欢打电话的好理由:

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

绝对不会溢出。

答案 1 :(得分:3)

欢迎来到buffer overflows的精彩世界。

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

答案 2 :(得分:2)

gets()不限制要读取的字符数,它不关心它们写入的位置,它假定目标缓冲区足够大。

为什么你会期望它停止阅读?

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

char c[3];

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

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

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

gets()实际上并不知道传递给它的内存块有多大。如果你给它更多的字符大于块大小,你就会调用未定义的行为。