请考虑以下代码:
#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]"
(请注意%
之前的空格),那么它可以正常工作。是否会自动接受先前输入缓冲区中的某些现有换行符?但是,刷新stdin
并不能解决这个问题。
原因是什么。
答案 0 :(得分:40)
在阅读完所需内容之后,您只需要“消费”'\n'
字符。使用以下格式指令:
"%[^\n]%*c"
哪个会将新行中的所有内容读入您传入的字符串中,然后将使用单个字符(换行符)而不将其分配给任何内容('*'
是'赋值抑制')。
否则,换行符将保留在输入流中,等待立即终止后续的"%[^\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");
答案 1 :(得分:7)
当您使用scanf()
读取字符串时,您的格式字符串(%[^\n]
)会告诉函数读取每个不是'\n'
的字符。这会在输入缓冲区中留下'\n'
个字符。因此,当您尝试阅读str2
和str3
时,scanf()
每次都会发现缓冲区中的第一个内容是'\n'
,并且由于格式字符串,因此不会删除它来自输入缓冲区。您需要的是从输入缓冲区读取的时间之间的getchar()
(通常紧跟在scanf()
之后)。由于缓冲区中已有'\n'
,因此您的程序似乎不会挂起,因为它不必等待getchar()
的输入接收。试试吧。 :)
对于那些不知道scanf()
修饰符的作用的人,这里是http://linux.die.net/man/3/scanf的相关摘录 -
[
匹配非空的序列 来自指定集合的字符 接受的人物;下一个指针 必须是指向char的指针,并且那里 必须有足够的空间容纳所有人 字符串中的字符加上a 终止空字节。通常的跳过 领先的白色空间受到抑制。 字符串由。组成 特定字符(或不存在) 组;该集由定义 开括号之间的字符[ 字符和一个小括号] 字符。该集不包括那些 字符,如果第一个字符 打开支架后是一个旋风 (^)。要包括一个紧密的括号 设置,使其成为之后的第一个角色 开口支架或旋风; 任何其他位置将结束该集。 连字符 - 也是 特别;放在另外两个之间 字符,它增加了所有干预 集合中的字符。包括一个 连字符,使它成为最后一个字符 在最后的紧密支架之前。对于 实例,[^] 0-9-]表示集合 “除了近括号外的一切,零 通过九,和连字符“。字符串 以a的外观结束 字符不在(或,与... 旋转,in)设置或当场 宽度耗尽。
答案 2 :(得分:3)
ALSO: 要读取字符串:
scanf("%[^\n]\n", a);
//这意味着在您遇到&#39; \ n&#39;之前阅读,然后删除&#39; \ n&#39;
:)
答案 3 :(得分:1)
只需在scanf()函数后使用getchar()即可。
答案 4 :(得分:0)
再加上上述答案 - 如果我们想要删除一些特定的模式,假设数字0-9,从输入流,那么我们将不得不使用getchar()来刷新缓冲区。
Merge the SID objects and drag in the final table.
Drag Contact Date & Contact Type objects in the final table.
Create detail variable for Contact date as "V Contact Date" and for Incident date as "V Incident Date".
Right click on the table->Format table-> checked the checkbox "Show rows with empty dimensions"
Drag below formula for calculated column and see.
=Sum(If([V Incident Date]<=RelativeDate([ V Contact Date];7) And ([V Incident Date]>=[ V Contact Date])) Then 1 Else 0)
所以这里如果你传递ashish019然后只有ashish将被复制到str而019将被留在缓冲区中,以便清除你需要多次getchar()。
答案 5 :(得分:-3)
在读取每个输入后使用fflush(stdin)
清除输入缓冲区。