8.5.1 使用缓冲输入
问题在于缓冲输入需要您按下回车键来提交您的输入。这一动作还传输一个程序必须处理的换行符。您必须使程序至少能够处理这种情况 。
程序清单8.4 guess.c程序
/*guess.c--一个低效且错误的猜数程序*/
#include <stdio.h>
int main (void)
{
int guess=1;
char response; /*添加一个char变量存储响应*/
printf("Pick an integer from 1 to 100.I will try to guess ");
printf("it.\nRespond with a y if my guess is right and with");
printf("\nan n if it is wrong.\n");
printf("uh...is your number %d?\n",guess);
while ((response = getchar())!='y') /*获取用户响应并和y进行比较*/
{
if (response=='n') /*if else 来区别字符n和以个的字符*/
printf("Well,then,is it %d\n",++guess);
else
printf("Sorry,I understand only y or n.\n");
while (getchar()!='\n') /*跳过输入的其他部分,包括换行符*/
continue;
}
printf("I knew I cloud do it !\n");
return 0;
}
8.5.2 混合输入数字和字符
getchar()读取每个字符,包括空格、制表符和换行符;而scanf()在读取数字时则会跟过空格 、制表符和换行符。
程序清单 8.5 showchar1.c
/*showchar1.c--带有一个较大的I/O问题的程序*/
#include <stdio.h>
void display(char cr,int lines ,int width);
int main (void)
{
int ch ; /*要打印的字符*/
int rows,cols; /*行数和列数*/
printf("Enter a character and two integers; \n");
while ((ch=getchar())!='\n')
{
scanf("%d %d",&rows,&cols);
display(ch,rows,cols);
printf("Enter another character and two integers; \n");
printf("Enter a newlines to quit. \n");
}
printf("Bye.\n");
return 0;
}
void display(char cr,int lines,int width)
{
int row,col;
for(row=1;row<=lines;row++)
{
for(col=1;col<=width;col++)
putchar(cr);
putchar('\n'); /*结束本行,开始新一行*/
}
}
该程序开始时表现很好。您输入c 2 3,程序就如期打印2行c字符,每行3个。然后该程序提示输入第二组数据,并在您还没有能做出响应之前就退出了。哪里出错了呢?又是换行符,这次是紧跟在第一个输入行的3后面的那个换行符。scanf()函数将该换行符留在了输入队列中。与scanf()不同,getchar()并不跳过该换行符。所以在循环的下一个周期,在您有机会输入任何其他内容之前,这一换行符由getchar()读出,然后将其赋值给ch,而ch为换行符正是循环终止的条件。
要解决这一问题,该程序必须跳过一个输入周期中键入的最后一个数字与下行开始处键入的字符之间的所有推行符或空格 。另外,如果getchar()判断之外还可以在scanf()阶段终止该程序,则会更好。
程序清单8.6 showchar2.c程序
/*showchar1.c--带有一个较大的I/O问题的程序*/
#include <stdio.h>
void display(char cr,int lines ,int width);
int main (void)
{
int ch ; /*要打印的字符*/
int rows,cols; /*行数和列数*/
printf("Enter a character and two integers; \n");
while ((ch=getchar())!='\n')
{
if(scanf("%d %d",&rows,&cols)!=2)
break; /*在scanf()阶段添加判断终止循环*/
display(ch,rows,cols);
while(getchar()!='\n')
continue; /*跳过输入的剩余部分,包括换行符*/
printf("Enter another character and two integers; \n");
printf("Enter a newlines to quit. \n");
}
printf("Bye.\n");
return 0;
}
void display(char cr,int lines,int width)
{
int row,col;
for(row=1;row<=lines;row++)
{
for(col=1;col<=width;col++)
putchar(cr);
putchar('\n'); /*结束本行,开始新一行*/
}
}
while语句使程序剔除scanf()输入后的所有字符,包括换行符。这样就让循环准备好读取下一行开始的第一个字符。这意味着您可以自由地输入数据。
通过使用一个if语句和一个break,如果scanf()的返回值不是2,您就中止了程序。这种情况在有一个或两个输入值不是整数或者遇到文件尾时发生。
来源:oschina
链接:https://my.oschina.net/u/2754880/blog/702477