我正在编写一个C程序,它有一个5元素数组来存储字符串。我正在使用gets()
来获取输入。当我输入超过5个字符然后输出字符串时,它只给了我输入的所有字符。我知道字符串被\0
终止,所以即使我超过了我的数组,它仍然会输出整件事情。
但我很好奇的是,gets()
存储输入的位置,缓冲区还是直接转到我的阵列?
如果我输入一个很长的字符串,gets()
会尝试将字符存储在不应该触及的记忆中吗?它会给我一个段故障吗?
答案 0 :(得分:6)
这就是gets
是邪恶的原因。它不检查数组绑定并经常调用未定义的行为。切勿使用gets
,而是使用fgets
顺便说一下,现在gets
已不再是C的一部分。它已在C11标准中删除,转而采用新的安全替代方法gets_s
1 (参见wiki)。所以,最好忘记gets
。
<子> 1。 C11:K.3.5.4.1 gets_s
功能
概要
#define _ _STDC_WANT_LIB_EXT1_ _ 1
#include <stdio.h>
char *gets_s(char *s, rsize_t n);
答案 1 :(得分:0)
gets()
会将字符存储在5元素缓冲区中。如果输入的字符数超过4个,则字符串字符的结尾将被遗漏,并且结果可能无法在程序中的任何字符串操作中正常工作。
答案 2 :(得分:0)
摘自Ubuntu Linux上的手册页
gets() reads a line from stdin into the buffer pointed to by s until
either a terminating newline or EOF, which it replaces with a null byte
('\0'). No check for buffer overrun is performed
字符串存储在缓冲区中,如果它太长则会在缓冲区后存储在连续的内存中。这可能导致无意中写入数据或SEGV故障或其他问题。这是一个安全问题,因为它可以用来将代码注入程序。
答案 3 :(得分:0)
gets()将您直接键入的字符存储到数组中,您可以安全地使用/修改它们。但实际上,正如haccks和unxnut正确陈述的那样,gets并不关心你给它存储其字符的数组的大小,当你输入的字符多于数组有空格时你可能最终会出现分段错误或其他一些奇怪的结果。
为了完整起见,gets()从一个名为stdin的缓冲文件中读取,该文件包含您键入的字符。更具体地说,它需要字符才能到达换行符。该换行符也会放入您的数组中,然后是'\ 0'终结符。正如haccks所说,你应该使用非常相似的fgets:
char buf[100]; // the input buffer
fgets(buf, 100, stdin); // reads until it finds a newline (your enter) but never
// more than 99 chars, using the last char for the '\0'
// you can now use and modify buf