2017-08-25 41 views
-2

scanf("%s"),scanf(”%[^\n]s")gets(a) C编程?scanf(“%s”,a)scanf(“%[^ n] s”,a)与C编程中的字符串得到(a)有什么区别?

scanf("%[^\n]s", a) 

scanf("%s", a) 

gets(a) 

采取字符数组输入三种方式之间的主要区别是什么?

+1

'puts()'用于输出,至少。什么是'a'?如果它是一个char数组或指向此类第一个元素的指针,那么'&a是错误的,因为它是指向char数组的指针或指向char的指针。 –

+2

您确定您的意思是''%s [^ \ n]“',而不是'”%[^ \ n]“'?也许你需要一个[很好的'scanf'(和家庭)参考](http://en.cppreference.com/w/c/io/fscanf)? –

+4

'scanf(“%s [^ \ n]”,a)'只是**错**。有一个转换说明符''和一个**不同的**转换说明符'[]'。他们不是要结合。 –

回答

2

首先,他们都已经不确定出于同样的原因行为:他们会读一些你无法预先知道字符,而是通过你的指针,你提供存储在哪里存储该数据,而这个存储有一些固定的大小。因此,总有输入可能会溢出您的缓冲区。你不应该在你的代码中使用这些行的任何

这就是说:

  • gets()读取输入并存储的线到您的缓冲区。它也读取换行符,但不存储。 此功能被设计破坏,因为有没有办法安全地使用它。永远不要使用它。已经从C11的C标准中删除了,所以你只能使用它与旧标准无论如何。正确的替代品是char a[100]; fgets(a, sizeof a, stdin);。但是,将换行符存储在缓冲区中。

  • scanf("%[^\n]s", ...)还将读取的输入。 []转换说明符采用被接受的列表或前面的^拒绝的字符。因此,使用此语法,它将接受任何字符,但换行符除外。因此,换行符将不会被这样读取s将在输入中进行搜索,字面意思是,这不是你的意思。 s[]不同转换说明符。要正确使用这个字段,您必须像这样使用字段:char a[100]; scanf("%99[^\n]", a);。请注意,您必须指定比缓冲区大小小,因为scanf()不包括附加为字符串结束标记的'\0'字符。

  • scanf("%s", ...)读取“”,这是它停靠在第一空白字符。正确使用这个,如上所述,使用类似char a[100]; scanf("%99s", a);的东西。

+0

爱词组”设计“....我知道你的意思,但它几乎听起来像设计师_meant_为'gets()'被打破;) –

+0

哈哈,从来没有想过这个*这样的短语。当然,我的意思是设计在一定程度上是错误的,这使得在实现中无法“修复”。 –

+0

“scanf(”%s“,...)读取一个”单词“,即它停在第一个空格字符处。”省略了前导空格被读取和丢弃的部分,然后开始读取“单词”。 – chux

4

scanf("%s",a);将跳过输入前导空格字符,将匹配字符,直到一个空白遇到字符(或者直到达到文件结束),将它们存储在由论证者指示的数组中吨。请注意,这容易受到缓冲区溢出的影响,所以最好包含一个宽度指定符,以提供从输入中读取的最大字符数。例如,如果a是100 char的数组,则应使用%99s;这为\0终止符留下了空间,该终止符自动由scanf()添加。

scanf("%s[^\n]",a);scanf("%[^\n]s", a);也可能是什么意思,而应该是:scanf("%[^\n]",a);%[]扫描集指令。没有必要遵循%[]指示与s,它只会告知scanf()%[]完成后在输入中匹配字面s。 scanset指令匹配方括号内描述的字符并将它们分配给相应的参数。当匹配失败时,该字符被放回到输入流中。在这里,^\n表示除了之外的所有字符应该匹配换行符,所以该指令将匹配字符,直到遇到换行符,并且换行符将保留在输入流中。关于指定最大宽度的相同建议也适用于此处:%99[^\n]以避免缓冲区溢出,如果a是100 char s的数组。请注意,%[^\n]指令将匹配任何不是\n的字符,包括其他空格字符。这意味着它将跳过前导空白字符(但是在输入的领先\n将导致指令立即失败,未做分配),而相比之下,%s,并将读取线包含输入空间。

puts(a);不读取输入,而是输出功能。请注意,该函数在打印参数后打印换行符。也许你打算在这个方法列表中包含gets()来收集输入。

gets(a); is an unsafe function在C99中已弃用,并且已从C11中的语言中完全删除。出于任何原因,您绝不应该使用此功能。该函数获取一行输入,读取字符,直到遇到换行符,或者直到达到文件结尾。换行符被丢弃;它不存储在a指示的数组中,并且不会返回到输入流。因此,当过去使用gets()时,它与puts()一起工作良好,它在打印参数后自动打印换行符。

最后,多一点信息,有fgets()。该函数获取一行输入,但需要一个大小参数,以避免缓冲区溢出。由于我前面的char a[100];例如,fgets()会被称为是这样的:

fgets(a, 100, stdin); 

或有时:

fgets(a, sizeof a, stdin); 

这里,fgets()读取最多一个字符少比大小参数指定的数,允许总是添加\0的空间。如果读取了\n,则它存储在a中。由于换行符不被丢弃,因此puts()在这里不起作用;经常在输入fgets()后需要删除换行符。

+0

对不起,我的最后一次编辑是在你精心设计的答案中发生的,OP显然在发布之前没有想过,请随时编辑它,我现在就放弃... –

+0

你是说'gets()'现在在答案中吗?我刚刚看到并正在更新.... –

+1

好吧...至少现在问题中的代码是OP的意思。我希望人们会花一秒钟的时间来证明他们在点击发布按钮之前所要求的内容:o –

相关问题