向scanf输入短语(“c”和“ch)。。。(%c表示序列,而不是单个符号)
我正在读S.Prata的书《C初级读物升级版》。第6章,控制问题#8:向scanf输入短语(“c”和“ch)。。。(%c表示序列,而不是单个符号),c,loops,scanf,C,Loops,Scanf,我正在读S.Prata的书《C初级读物升级版》。第6章,控制问题#8: //如果有输入,往西走,年轻人!,以下每一项都会是什么 //程序为输出而生产?(在中的空格字符后面加上!) //ASCII序列。) #包括 内部主(空){ char ch; scanf(“%c”和“ch”); 而(ch!=“g”){ printf(“%c”,ch); scanf(“%c”和“ch”); } 返回0; } 问题是。。。据我所知,
//如果有输入,往西走,年轻人!,以下每一项都会是什么
//程序为输出而生产?(在中的空格字符后面加上!)
//ASCII序列。)
#包括
内部主(空){
char ch;
scanf(“%c”和“ch”);
而(ch!=“g”){
printf(“%c”,ch);
scanf(“%c”和“ch”);
}
返回0;
}
问题是。。。据我所知,
中的%c
应用于单个字符,而不是用于“向西走,年轻人!”之类的短语。为什么这个程序读取所有行并存储所有行(除了最后一个字),而不仅仅是第一个字符?它是否自动将内容作为数组存储在scanf
中
我以为它只会打印“G”。。。但它实际上打印的是“向西走,年轻人”。为什么?它不是%s
,而是%c
我想这可能是因为
%c
存储了“char”的所有输入。。但在规范中,它说它只存储单个字符,而不是几个字符。该程序只是逐个读取输入的所有字符
对于输入,例如
Go west, young man!
然后第一次调用scanf读取单个字符'G'
。然后在循环中打印单个'G'
,然后读取单个字符'o'
。然后在循环的下一次迭代中,您打印单个字符'o'
(在上一次迭代中读取),然后读取空格'
。等等
还要注意,
'G'
不等于'G'
。字符比较区分大小写。有一个循环,循环体中有scanf()
while ( ch != 'g' )
因此,它继续读取缓冲区中的输入,直到找到一个'g'
因此,对于输入
'Go west, young man!'.
^---------------- here is the 'g'
它将在每次迭代中一个接一个地读取字符,直到读取
'g'
并满足循环的退出条件。字符ch
永远不会存储整个字符串,它只存储一个字符。您得到的输出不是单个printf
执行给出的输出,而是多次执行printf
s(循环进入多次)。您可以通过将代码更改为:
#包括
内部主(空)
{
char ch;
scanf(“%c”和“ch”);
而(ch!=“g”)
{
printf(“打印:%c\n”,ch);
scanf(“%c”和“ch”);
}
返回0;
}
现在,让我们看看为什么循环会多次进入
您在循环外的scanf中输入了许多字符,然后在循环中您希望它打印第一个字符,这是完全正确的。但是,您认为它将再次等待用户输入,这是不正确的。在第一个scanf
中,当您输入多个字符时,它只读取第一个字符。但是在stdin(标准输入)中有一个隐藏的光标,可以跟踪所读取的内容。当您输入“Go west,young man!”时,G
存储在ch中,光标放在o
之前。下次调用scanf
时,它会查看光标位置并找到一个o
,因此它不会等待用户输入,而是直接读取。等等
总而言之,我怀疑您的问题在于您误解了scanf的工作原理。您认为无论何时调用它都将等待用户输入。情况并非如此,它可能从以前的输入中读取
如果您想让下一个scanf
s忽略长的第一个输入,您应该实际阅读它(或者查找stdin,它将在Windows中工作,但在Linux中不工作)。例如:
#包括
内部主(空)
{
char ch;
scanf(“%c”和“ch”);
while(getchar()!='\n');//转到stdin的末尾。
//前一行可以替换为fseek(stdin,0,SEEK_END);但它只能在Windows下工作。
而(ch!=“g”)
{
printf(“打印:%c\n”,ch);
scanf(“%c”和“ch”);
}
返回0;
}
是的,这是可以理解的。问题是-为什么scanf()存储缓冲整个短语“向西走,年轻人!”,不仅仅是“G”。因为它是scanf(“%c”和&ch),而不是scanf(“%s”和&ch)@给定的igroglazch
是一个char
,scanf(“%s”,&ch)代码>是错误的。这就是说,使用%s
,输入一次匹配并存储,不需要循环。但是,在这种情况下,由于循环,它会一个接一个地从输入缓冲区读取数据代码>读取、匹配ad,每次存储一个字符。结合循环,它读取多个..@igroglaz将while替换为if,那么您将获得预期的输出。因为while检查字符串中的“g”,并执行到“g”。伙计们,谢谢,但我仍然没有得到答案。我想是我的英语不好,所以很难理解我的意思。再一次:我在书中读到%c-代表单个字符。所以当这个程序有scanf(“%c”,&ch)时;(开头!字符串#4)-它应该只存储短语的第一个符号,因为它是%c,而不是%s,不是吗?为什么string#4中的scanf(“%c”、&ch)”会存储这个长短语,而不仅仅是存储“G”?程序的另一部分非常简单,不易理解。问题是这个短语的初始存储,它变成了“字符串”存储,而scanf得到了%cyep,这是可以理解的。问题是-为什么scanf()存储缓冲整个短语“向西走,年轻人!”,不仅仅是“G”。因为它是scanf(“%c”和&ch),而不是scanf(“%s”和&ch)@igroglaz和我告诉过你:它不读取“整个短语”,而是一次读取一个字符。问题是关于将长短语存储在%c缓冲区(单个字符点)中,而不是从buffer@igroglaz但正如我在另一篇评论中所说,你的程序不会在任何地方存储任何“长短语”,你存储的只是一个字符
'Go west, young man!'.
^---------------- here is the 'g'