关于C中的gets()

我正在编写一个C程序,它有一个5元素数组来存储字符串。 我正在使用gets()来获取输入。 当我输入超过5个字符然后输出字符串时,它只给了我输入的所有字符。我知道字符串以\0结束,所以即使我超过了我的数组,它仍然会输出整个字符。

但我很好奇的是, gets()存储输入的位置,缓冲区还是直接进入我的数组?
如果我输入一个很长的字符串,会gets()尝试将字符存储在不应该触及的记忆中吗? 它会给我一个段故障吗?

这就是为什么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  char *gets_s(char *s, rsize_t n); 

gets()将字符存储在5元素缓冲区中。 如果键入的字符数超过4个,则字符串字符的结尾将被遗漏,并且结果可能无法在程序中的任何字符串操作中正常工作。

摘自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故障或其他问题。 这是一个安全问题,因为它可以用来将代码注入程序。

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