同时使用两个scanf(%s)有什么问题

时间:2016-07-02 12:08:41

标签: c string scanf

为什么第二个scanf不接受任何输入? %s cancatanae字符串?

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char string1[50];
char string2[50];


scanf("%[^\n]s",string1);
scanf("%[^\n]s",string2);

printf("\nfirst string :%s \n",string1);
printf("\nsecnd string :%s \n",string2);

return 0;
}

输入:这是bbc [enter]

输出:第一个字符串:这是bbc         第二个字符串:{some characters symbol}

3 个答案:

答案 0 :(得分:1)

问题是,您的scanf格式字符串要求字符串以s结尾:%[^\n]被解释为格式说明符,然后您有一个s必须与输入匹配。由于第二个字符串未在s中开始,因此第二个scanf不会读取任何内容。

用空格替换s将解决问题:

scanf("%[^\n] ", string1);
//           ^
// Space is important

更好的是,在%[^\n]中的scanf前面放置空格:

scanf("%49[^\n]", string1);
scanf(" %49[^\n]", string2);

由于您的字符串缓冲区容量有限,因此必须设置限制为49以避免缓冲区溢出

答案 1 :(得分:1)

"%[^\n]s"告诉scanf“吃掉”所有不是换行符的字符并将它们放入参数中;这意味着,在第一个scanf返回后,它将离开换行符,使其停止在读缓冲区中。下一个scanf找到它并立即停止阅读 - 毕竟,你告诉它读取第一个换行符!

这里的解决方案可以是使用"%[^\n]s\n",它甚至可以“吃掉”字符串后面的换行符,甚至是"%[^\n]s ",其中空格是“魔法”,因为它告诉{{ 1}}吃掉它能找到的所有其他空格,其中包括换行符(但请注意,如果你想在下一行读取一个空字符串,这是一个坏主意。)

更简单一点,您可以简单地使用scanf,与fgets(string1, sizeof(string1), stdin) scanf不同,可以安全地防止缓冲区溢出(是的,您可以使%s安全,但它更多的工作)。请注意,%s会将尾随换行符放入字符串中。

答案 2 :(得分:-1)

您的代码只会读取一个输入。由于%[^ \ n] s无法阅读&#39;

将以下一个替换为两个scanf()语句。 刚刚在我的系统上执行了你的代码。

  

scanf(&#34;%[^ \ n] s%[^ \ n] s&#34;,string1,string2);

或者只是从语句中删除s并添加空格。

  

scanf(&#34;%[^ \ n]&#34;,string1);
  scanf(&#34;%[^ \ n]&#34;,string2);

检查输入两个字符串,并显示正确的输出。