scanf:“%[^\n]”跳过第二个输入,但“” %[^\n]”没有。为什么?
考虑以下代码:
#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;
}
执行时,仅第一个 scanf
停止提示。程序不会在接下来的 scanf 中停止。但如果格式字符串由"%[^\n]"
改为"%[^\n]"
(注意%<前面的空格) /code>),然后就可以正常工作了。是否自动接受先前输入缓冲区中的某些现有换行符?但刷新 stdin 并不能解决这个问题。
这是什么原因呢。
Consider the following code:
#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;
}
When it is executed only the first scanf
stops for the prompt. The program does not stop for the next scanf
s. But if the format string is changed from "%[^\n]"
to " %[^\n]"
(note the blank space before %
), then it works okay. Does some existing newline character from the previous input buffer is automatically accepted ? But flushing stdin
does not solve this.
What is the cause of this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您只需在阅读完所需内容后“使用”
'\n'
字符即可。使用以下格式指令:它将把换行符之前的所有内容读入您传入的字符串中,然后将使用单个字符(换行符)而不将其分配给任何内容(
'*'
是 '分配抑制')。否则,换行符将留在输入流中,等待立即终止后续的
"%[^\n]"
格式指令。将空格字符添加到格式指令 (
" %[^\n]"
) 的问题是该空格将匹配任何 空格。因此,它会吃掉前一个输入末尾的换行符,但它也会吃掉任何其他空格(包括多个换行符)。更新您的示例:
You just need to 'consume' the
'\n'
character after you've read what you want. Use the following format directive:Which will read everything up to the newline into the string you pass in, then will consume a single character (the newline) without assigning it to anything (that
'*'
is 'assignment suppression').Otherwise,the newline is left in the input stream waiting to immediately terminate the the subsequent
"%[^\n]"
format directives.The problem with adding a space character to the format directive (
" %[^\n]"
) is that the space will match any white space. So, it will eat the newline from the end of the previous input, but it will also eat any other whitespace (including multiple newlines).Update to your example:
当您使用
scanf()
读取字符串时,您的格式字符串 (%[^\n]
) 会告诉函数读取除' 之外的每个字符\n'
。这会将'\n'
字符留在输入缓冲区中。因此,当您尝试读取str2
和str3
时,scanf()
会发现缓冲区中的第一个内容是'\n'< /code> 每次,由于格式字符串的原因,不会将其从输入缓冲区中删除。您需要的是从输入缓冲区读取数据的时间之间的
getchar()
(通常紧接在scanf()
之后)。由于缓冲区中已经存在'\n'
,因此您的程序不会出现挂起的情况,因为它不必等待getchar()
的输入收到。尝试一下。 :)对于那些不知道
scanf()
修饰符的作用的人,这里是来自 http://linux.die.net/man/3/scanf -When you use
scanf()
to read the strings, your format string (%[^\n]
) tells the function to read every character that is not'\n'
. That leaves the'\n'
character in the input buffer. So when you try to readstr2
andstr3
,scanf()
finds the first thing in the buffer is'\n'
each time and, because of the format string, doesn't remove it from the input buffer. What you need is agetchar()
between the times that you read from the input buffer (often placed immediately afterscanf()
). Since there is already a'\n'
in the buffer, your program won't appear to hang because it won't have to wait for input forgetchar()
to receive. Try it. :)For those who haven't a clue what that
scanf()
modifier does, here is a relevant excerpt from http://linux.die.net/man/3/scanf -还:
读取字符串:
// 这意味着读取直到遇到 '\n',然后丢弃该 '\n'
:)
ALSO:
To read a string:
// it means read until you meet '\n', then trash that '\n'
:)
只需在 scanf() 函数之后使用 getchar() 即可。
Just use a getchar() after the scanf() function.
只是在上面的答案的基础上进一步添加一点——
如果我们想从输入流中删除一些特定的模式,假设数字 0-9,那么我们将不得不使用 getchar() 来刷新缓冲区。
因此,如果你传递 ashish019 ,那么只有 ashish 会被复制到 str ,而 019 会留在缓冲区中,因此为了清除,你需要多次 getchar() 。
Just adding a bit further to above answer-
If we want to remove some specific pattern, suppose numbers 0-9, from input stream then we will have to use getchar() for flushing buffer.
So here if you pass ashish019 then only ashish will be copied to str and 019 would be left in buffer so for clearing that you need getchar() multiple times.
读取每个输入后,使用 fflush(stdin) 清除输入缓冲区。
use
fflush(stdin)
to clear the input buffer after reading each input.