scanf:"%[^ \n]"跳过第二个输入,但"%[^ \n]"不跳过.为什么?

pho*_*xis 28 c scanf

请考虑以下代码:

#include <stdio.h>

int main (void)
{
  char str1[128], str2[128], str3[128];

  printf ("\nEnter str1: ");
  scanf ("%[^\n]", str1);
  printf ("\nstr1 = %s", str1);

  printf ("\nEnter str2: ");
  scanf ("%[^\n]", str2);
  printf ("\nstr2 = %s", str2);

  printf ("\nEnter str3: ");
  scanf ("%[^\n]", str3);
  printf ("\nstr3 = %s", str3);

  printf ("\n");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当它仅执行scanf提示的第一站时.该计划不会停止下一个scanfs.但是如果格式字符串从更改"%[^\n]"" %[^\n]"(注意之前的空格%),那么它可以正常工作.是否会自动接受先前输入缓冲区中的某些现有换行符?但冲洗stdin并不能解决这个问题.

造成这种情况的原因是什么.

Mic*_*urr 43

你只需要'\n'在阅读完你想要的东西后"消费"这个角色.使用以下格式指令:

"%[^\n]%*c"
Run Code Online (Sandbox Code Playgroud)

哪个会将新行中的所有内容读入您传入的字符串中,然后将使用单个字符(换行符)而不将其分配给任何内容(即'*'"赋值抑制").

否则,换行符将保留在输入流中,等待立即终止后续"%[^\n]"格式指令.

向格式指令(" %[^\n]")添加空格字符的问题是空格将匹配任何空格.因此,它将从前一个输入结束时吃掉换行符,但它也会吃掉任何其他空格(包括多个换行符).

更新您的示例:

  char* fmt = "%[^\n]%*c";

  printf ("\nEnter str1: ");
  scanf (fmt, str1);
  printf ("\nstr1 = %s", str1);

  printf ("\nEnter str2: ");
  scanf (fmt, str2);
  printf ("\nstr2 = %s", str2);

  printf ("\nEnter str3: ");
  scanf (fmt, str3);
  printf ("\nstr2 = %s", str3);

  printf ("\n");
Run Code Online (Sandbox Code Playgroud)

  • @Dogbert:说实话,我不是使用`scanf()`来解析输入的忠实粉丝.在大多数情况下,我可能更喜欢将一行输入完全读入缓冲区,然后使用`sscanf()`,`strtok()`或更好的东西来解析该缓冲区. (3认同)

小智 7

当你scanf()用来读取字符串时,你的格式字符串(%[^\n])告诉函数读取每个不是的字符'\n'.这会将'\n'字符留在输入缓冲区中.所以,当你尝试读取str2str3,scanf()发现在缓冲区中的第一件事情就是'\n'每次和,因为格式的字符串,不从输入缓冲区中取出.您需要的是getchar()在从输入缓冲区读取的时间之间(通常紧接在之后放置scanf()).由于'\n'缓冲区中已有a ,因此您的程序不会挂起,因为它不必等待输入getchar()接收.试试吧.:)

对于那些还没有什么线索是谁scanf()修改器,这里是从相关的摘录http://linux.die.net/man/3/scanf -

[

匹配指定的一组接受字符中的非空字符序列; 下一个指针必须是指向char的指针,并且字符串中的所有字符必须有足够的空间,加上一个终止空字节.通常跳过前导空格被抑制.该字符串由特定集合中的字符组成(或不在其中); 该集合由open括号[character和close bracket]字符之间的字符定义.如果开括号后的第一个字符是旋音(^),则该组将排除这些字符.要在组中包含一个小括号,请将其作为开括号或旋转后的第一个字符; 任何其他位置将结束该集.连字符 - 也很特别; 当放置在两个其他字符之间时,它会将所有插入的字符添加到集合中.要包含连字符,请将其设置为最后一个关闭括号之前的最后一个字符.例如,[^] 0-9-]表示集合"除了近括号,零到九和连字符之外的所有内容".该字符串的结尾是字符的外观不在(或带有旋律,in)设置或字段宽度用完时.

  • 请注意,C99标准实际上并未指定`"%["`的行为. (2认同)