如果代码
scanf("%s\n",message)
对比
gets(message)
它们之间有什么区别?似乎两者都将输入传递给消息。
针对您的特定情况,基本区别如下:
scanf()
在遇到whitespace
、newline
或EOF
时结束输入。
gets()
将空格视为输入字符串的一部分,在遇到newline
或EOF
时结束输入。
然而,为了避免缓冲区溢出错误和减少安全风险,更安全的方法是使用fgets()
。
scanf("%s\n",message)
不会在遇到空格或换行符时停止输入。"%s\n"
会导致scanf()
执行以下操作:1)扫描所有的空白输入并将其丢弃;2)扫描所有的非空白输入并将其保存到message
中,最后附加'\0'
;3)扫描所有的空白输入并将其丢弃,直到遇到一个非空白字符,该字符被放回到stdin
以供下一次IO调用使用。 - chux - Reinstate Monica澄清:在下文中,如果“safe”没有正确使用不会导致麻烦,则我认为其是“安全的”,如果无法规避“不安全性”,则认为其是“unsafe”。
就安全性而言,从标准输入读取数据的两种方法并无区别,都有可能导致message溢出,如果用户输入的数据超过message提供的内存空间。scanf("%s\n",message)
vs
gets(message)
What's the difference?
char message[42];
...
scanf("%41s", message); /* Only read in one few then the buffer (messega here)
provides as one byte is necessary to store the
C-"string"'s 0-terminator. */
gets()
函数无法指定读取的最大字符数,因此不应该使用该函数!scanf()
是一个该死的、可恶的、该死的不安全的家伙。我几乎总是拒绝使用它。... - alkgets
读取到EOF或\n
,而scanf("%s")
读取到任何空格为止。 scanf
提供更多的格式选项,但同时它的类型安全性比gets
差。scanf
是标准C函数,而gets
已被从语言中删除,因为它既是多余的又很危险:没有保护措施来防止缓冲区溢出。然而,scanf
也存在同样的安全漏洞,因此这两个函数都不应该用于生产代码。fgets
,甚至C标准本身也建议这样做,请参见C11 K.3.5.4.1:推荐实践
6. fgets函数允许正确编写的程序安全地处理太长以至于无法存储在结果数组中的输入行。一般情况下,这要求调用者在结果数组中注意换行符的存在或不存在。 请考虑使用fgets(以及基于换行符的任何必需处理),而不是gets_s。
(强调我的)
scanf("%s")
会读取并丢弃任何前导空格,然后扫描并保存非空格字符,直到随后的空格或EOF
。 - chux - Reinstate Monicagets
- 从标准输入读取字符并将它们存储为字符串。
scanf
- 从标准输入中读取数据,并根据scanf
语句中指定的格式(如%d
,%f
,%s
等)将其存储。
gets:->
gets()
函数从标准输入中读取一行,并将其存储到由指针s
指向的缓冲区,直到遇到换行符或者EOF,然后用空字符('\0'
)替换它们。
BUGS:->
切勿使用
gets()
。因为在不知道数据长度的情况下,在使用gets()
时无法确定它会读入多少个字符,并且gets()
会继续存储超出缓冲区末尾的字符,所以使用它非常危险,它已经被用于破坏计算机安全。请改用fgets()
。
scanf:->
scanf()
函数从标准输入流stdin读取输入;
BUG:->
有时候当涉及数组和字符串概念时,
scanf
会产生一些边界问题。
scanf
和gets
不同,scanf
需要指定格式,而gets
则可以输入字符、字符串、数字和空格。
scanf
在遇到空格时结束输入。gets()
还是scanf()
都需要确保字符串是有效的指向足够长的数组的指针。否则会导致缓冲区溢出。fgets()
,但这完全取决于使用情况。scanf 不接受空格的概念是完全错误的。如果您使用此代码部分,它将同时接受空格:
#include<stdio.h>
int main()
{
char name[25];
printf("Enter your name :\n");
scanf("%[^\n]s",name);
printf("%s",name);
return 0;
}
在编程中,换行符只会停止输入。这意味着只有在按下回车键时才会停止输入。
因此,scanf和gets函数基本上没有区别。这只是一种巧妙的实现方式。
scanf()
是更加灵活的工具,而 gets()
一次只能获取一个变量。
gets() 是不安全的,例如:char str[1]; gets(str) 如果你输入的内容超过了长度,它会以 SIGSEGV 结束。如果只能使用 gets,请使用 malloc 作为基本变量。
gets()
是不安全的,但是:如果您输入的内容超出了长度,那么怎么办?您如何在C中输入一个“字符串”的长度?您似乎把一些事情搞混了。 - alk
scanf()
是标准的 C 函数,而gets()
已经不再是标准函数。 - alkgets
被有意弃用的事实?即使是4年前的回答也建议像避瘟疫一样避免使用gets
。 - user3920237scanf()
同样不安全...而且每个人都忽略了可怜的fgets()
,它应该是获取用户输入的唯一方法。 - The Paramagnetic Croissantscanf()
是完全安全的。 - alkscanf()
比正确使用fgets()
要难得多。 - The Paramagnetic Croissant