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

时间:2017-08-25 07:30:12

标签: c scanf

C编程中scanf("%s")scanf(”%[^\n]s")gets(a)之间有什么区别?

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

scanf("%s", a)

gets(a)

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

2 个答案:

答案 0 :(得分:4)

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

scanf("%s[^\n]",a);scanf("%[^\n]s", a);都不是我的意思,而应该是:scanf("%[^\n]",a);%[] scanset 指令。没有必要使用%[]跟随s指令,这只会在scanf()完成后告诉s与输入中的文字%[]匹配。 scanset指令匹配括号中描述的字符,并将它们分配给相应的参数。当匹配失败时,该字符将放回输入流中。这里,^\n表示应该匹配换行符的之外的所有字符,因此该指令将匹配字符,直到遇到换行符,并且换行符将保留在输入流中。关于指定最大宽度的相同建议也适用于:%99[^\n]以避免缓冲区溢出,如果a是100 char s的数组。请注意,%[^\n]指令将匹配任何不是\n的字符,包括其他空白字符。这意味着它将跳过前导空格字符(但输入中的前导\n将导致指令立即失败,而不进行赋值),与{{1 },并将读取包含空格的输入的

%s不读取输入,但是是输出函数。请注意,此函数在打印其参数后打印换行符。也许您打算在此方法列表中包含puts(a);来收集输入。

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

最后,有关更多信息,请fgets()。此函数获取一行输入,但采用size参数,以避免缓冲区溢出。鉴于我之前的char a[100];示例,fgets()将被称为:

fgets(a, 100, stdin);

或有时:

fgets(a, sizeof a, stdin);

在这里,fgets()最多只能读取一个字符而不是size参数指定的数字,从而允许\0的空间,它总是被添加。如果读取\n,则会将其存储在a中。由于换行不被丢弃,puts()在这里不起作用;通常在使用fgets()输入后需要删除换行符。

答案 1 :(得分:2)

首先,他们所有人都有未定义的行为出于同样的原因:他们会读取许多字符你事先无法知道,但通过你的指针,您提供存储此数据的存储位置,并且此存储具有一些固定大小。因此,始终输入可能会溢出您的缓冲区。您不应该在代码中使用任何这些行。

那说:

  • gets()读取输入的并将其存储到缓冲区。它还会读取换行符,但不会存储。 此功能因设计错误,因为无法安全使用。不要使用它。它已被C11中的C标准删除,因此您无论如何都只能使用旧标准。正确的替换是char a[100]; fgets(a, sizeof a, stdin);。但将换行符存储在缓冲区中。

  • scanf("%[^\n]s", ...)还会读取输入的[]转化说明符会列出已接受的列表,或者前面带有^的拒绝字符列表。因此,使用此语法,它将接受任何字符换行符。因此,不会以这种方式读取换行符 。 {<1}}将在输入字面上搜索,这不是你的意思。 ss不同的转换说明符。要正确使用此字段,您必须使用如下字段:[]。请注意,您必须指定少一个而不是缓冲区大小,因为char a[100]; scanf("%99[^\n]", a);不计算附加为字符串结束标记的scanf()字符。

  • '\0'读取“单词”,即它停在第一个空白字符处。要正确使用此功能,请使用scanf("%s", ...)

  • 之类的内容