c语言怎么换行输入多组数据

大部分人偶尔会写一些中看不中用的程序。还好,C提供了大量工具让输入更顺畅,处理过程更顺利。不过,学习这些工具会导致新的问,比如printf与scanf的快捷形式putchar与getchar。

1.使用缓冲输入

缓冲输入用起来比较方便,因为在把输入发送给程序之前,用户可以编辑输入。但是,在使用输入的字符时,它也会给程序员带来麻烦。前面示例中看到的问题是,缓冲输入要求用户按下Enter键发送输入。这一动作也传送了换行符,程序必须妥善处理这个麻烦的换行符。我们以一个猜谜程序为例。用户选择一个数字,程序猜用户选中的数字是多少。该程序使用的方法单调乏味,先不要在意算法,我们关注的重点在输入和输出。下面是猜谜程序的最初版本,后面我们会改进。

/* guess.c -- an inefficient and faulty number-guesser */
#include <stdio.h>
int main(void)
{
int guess = 1;
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 (getchar() != 'y')      /* get response, compare to y */
printf("Well, then, is it %d?\n", ++guess);
printf("I knew I could do it!\n");
return 0;
}

下面是程序的运行示例:

Pick an integer from 1 to 100. I will try to guess it.

Respond with a y if my guess is right and with

an n if it is wrong.

Uh...is your number 1?

n

Well, then, is it 2?

Well, then, is it 3?

n

Well, then, is it 4?

Well, then, is it 5?

y

I knew I could do it!

撇开这个程序糟糕的算法不谈,我们先选择一个数字。注意,每次输入n时,程序打印了两条消息。这是由于程序读取n作为用户否定了数字1,然后还读取了一个换行符作为用户否定了数字2。

一种解决方案是,使用while循环丢弃输入行最后剩余的内容,包括换行符。这种方法的优点是,能把no和no-way这样的响应视为简单的n。而第一个版本会把no当作两个响应。下面用循环修正这个问题:

while (getchar() != 'y')   /* get response, compare to y */
{
printf("Well, then, is it %d?n", ++guess);
while (getchar() != '\n')
continue;          /* skip rest of input line    */
}

下面是程序的运行示例:

Pick an integer fromxs 1 to 100. I will try to guess it.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
n
Well, then, is it 2?
no
Well, then, is it 3?
no sir
Well, then, is it 4?
forget it
Well, then, is it 5?
y
I knew I could do it

这的确是解决了换行符的问题。但是,该程序还是会把f视为n。我们用if语句筛选其他响应。首先,添加一个char类型的变量存储响应:

: char response;

修改后的循环如下:

现在,程序的运行示例如下:

while ((response = getchar()) != 'y')     /* get response */
{
if (response == 'n')
printf("Well, then, is it %d?n", ++guess);
else
printf("Sorry, I understand only y or n.n");
while (getchar() != 'n')
continue;                 /* skip rest of input line */
}

在编写交互式程序时,应该事先预料到用户可能会输入错误,然后设计程序处理用户的错误输入。在用户出错时通知用户再次输入。当然,无论你的提示写得多么清楚,总会有人误解,然后抱怨这个程序设计得多么糟糕。

2 混合数值和字符输入

假设程序要求用getchar()处理字符输入,用scanf()处理数值输入,这两个函数都能很好地完成任务,但是不能把它们混用。因为getchar()读取每个字符,包括空格、制表符和换行符;而scanf()在读取数字时则会跳过空格、制表符和换行符。

我们通过程序清单8.5来解释这种情况导致的问题。该程序读入一个字符和两个数字,然后根据输入的两个数字指定的行数和列数打印该字符。

/* showchar1.c -- program with a BIG I/O problem */
#include <stdio.h>
void display(char cr, int lines, int width);
int main(void)
{
int ch;             /* character to be printed    */
int rows, cols;     /* number of rows and columns */
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 newline 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');  /* end line and start a new one */
}
}

注意,该程序以int类型读取字符(这样做可以检测EOF),但是却以char类型把字符传递给display()函数。因为char比int小,一些编译器会给出类型转换的警告。可以忽略这些警告,或者用下面的强制类型转换消除警告:

display(char(ch), rows, cols);

在该程序中,main()负责获取数据,display()函数负责打印数据。下面是该程序的一个运行示例,看看有什么问题:

Enter a character and two integers:

c 2 3

ccc

ccc

Enter another character and two integers;

Enter a newline to quit.

Bye.

该程序开始时运行良好。你输入c 2 3,程序打印c字符2行3列。然后,程序提示输入第2组数据,还没等你输入数据程序就退出了!这是什么情况?又是换行符在捣乱,这次是输入行中紧跟在3后面的换行符。scanf()函数把这个换行符留在输入队列中。和scanf()不同,getchar()不会跳过换行符,所以在进入下一轮迭代时,你还没来得及输入字符,它就读取了换行符,然后将其赋给ch。而ch是换行符正式终止循环的条件。

要解决这个问题,程序要跳过一轮输入结束与下一轮输入开始之间的所有换行符或空格。另外,如果该程序不在getchar()测试时,而在scanf()阶段终止程序会更好。修改后的版本如下。

/* showchar2.c -- prints characters in rows and columns */
#include <stdio.h>
void display(char cr, int lines, int width);
int main(void)
{
int ch;             /* character to be printed      */
int rows, cols;     /* number of rows and columns   */
printf("Enter a character and two integers:n");
while ((ch = getchar()) != 'n')
{
if (scanf("%d %d",&rows, &cols) != 2)
break;
display(ch, rows, cols);
while (getchar() !=  'n')
continue;
printf("Enter another character and two integers;n");
printf("Enter a newline 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');  /* end line and start a new one */
}
}

while循环实现了丢弃scanf()输入后面所有字符(包括换行符)的功能,为循环的下一轮读取做好了准备。该程序的运行示例如下:

Enter a character and two integers:
c 1 2
cc
Enter another character and two integers;
Enter a newline to quit.
! 3 6
!!!!!!
!!!!!!
!!!!!!
Enter another character and two integers;
Enter a newline to quit.
Bye.

在if语句中使用一个break语句,可以在scanf()的返回值不等于2时终止程序,即如果一个或两个输入值不是整数或者遇到文件结尾就终止程序。

原创文章,作者:发布专员,如若转载,请注明出处:https://ziliaobaba.com/37044.html

(0)
发布专员发布专员
上一篇 2023年11月27日 15:48
下一篇 2023年12月16日 22:57

相关推荐

  • 游戏里的副本是什么意思?游戏副本

    副本是如今许多游戏中的一个重要玩法,那么副本是什么呢?根据百度百科的解释,副本是游戏里的一个特色玩法,主要为玩家带来装备、道具、游戏资源的产出,满足玩家的游戏进程。   那么“副本”这个词是怎么诞生的…

    2022年11月19日
  • 领导检查工作方法(领导来单位检查工作的通知)

    2021年是全国各行各业全面贯彻落实国家"十四五"规划的开局年,也是国有施工企业各级领导干部及广大员工为实现"十四五"规范拼搏奉献的开局年。值处施工企业年终突击检查工作之际,作为国有施工企业退休干部的一员,以关心企业发展的目的,近日,从企业部分长年奋斗在施工生产一线的员工中,进行一次员工队伍思想工作

    2022年1月5日
  • 苹果电脑怎么连接打印机(连接打印机和电脑使用教程)

    打印机连接电脑,你需要做的是安装打印机驱动程序,这样打印机才能读懂电脑给它下达的指令。文章分为四个部分:一、了解自己打印机的品牌型号二、下载官方的打印机驱动程序三、安装打印机驱动程序四、打印测试现在的打印机品牌有惠普、佳能、爱

    2022年1月1日
  • 自己怎么做小程序商城

    小程序商城的发展越来越快,它可以帮助企业更好地推广和销售产品,让消费者更加便捷地购买商品。作为一个企业,如何做一个小程序商城,让消费者更加便捷地购买商品,是一个值得深思的问题。 一、准备工作 1、确定小…

    投稿 2023年4月21日
  • dnf2022女气功加点(女气功加点攻略)

    DNF110级更新,全职业加点变更,很多兄弟私信秀儿,女气功的110级如何加点,粉丝的需求,就是秀儿的追求,在此分享秀儿的两套加点方案,希望能够对兄弟们有所帮助。 方案一:CP武器念气波流 【通用技能】暴击满(可…

    2022年11月9日
  • 什么歌最伤感?最新伤感歌曲2022催泪

    1天堂之泪 - 埃里克克莱普顿   这首歌讲述的是一个父亲失去了自己的孩子,真实的事件更能触动人的内心。沉重的气氛里带着对孩子的祝福和不舍,甚至可以感受到他失去自己的孩子是多么的痛苦,天堂有泪水还会有幸…

    2022年10月7日
  • 二表姐的新家如何装修?新家装修攻略细节

    表姐的新家历经3个月时间终于完成装修,便开始嘚瑟装修得有多么好看,我也顺势的去她家参观一下,看看是否真的如同传说中的一样漂亮? 一、客厅 表姐说刷大白墙容易脏而且太单调了,便了刷了浅黄色乳胶漆,同时电视…

    2021年11月3日
  • nike跑步鞋哪个系列好(nike跑步鞋有哪些系列)

    耐克和阿迪,一直是运动鞋品牌中的常青藤。自它们成立以来,就没有从人们的视线中退出过。长年占据运动鞋品牌销量的榜首和榜二,虽然在今年上半年的时候,阿迪达斯的市值一度被安踏超越,但是之后阿迪又重整旗鼓,再一次夺回属于它“千年老二”的位置。耐克和阿迪体量很大,覆盖的领域也很广,但是规模庞大的

    2022年1月3日
  • 中国在世界上受欢迎吗?中国在世界上的地位

    “中国影响全球政治舞台” 《参考消息》:您怎么看待中国过去这十年的发展? 伊沃·约西波维奇:中国这十年绝对是成功的十年。这十年来,中国取得了巨大进步、发生了巨大变化,不仅体现在经济发展方面,也体现在全球政…

    投稿 2022年10月17日
  • 夏天穿什么裤子?最百搭的裤子

    初夏的裤子怎么穿?今天,我们来聊聊裤子吧,关于它的风格穿搭之道。 说到裤装,老生常谈的话题,洛薇分享也不下N多遍了。很多基础的陈词滥调,再拿来啰嗦也没有多大意义。善于发现“新奇”,是我的使命。 不甘于现状…

    2021年11月11日