《C++ Primer》(5th)习题解答——8.1(cin对象浅析)

题目描述

代码

#include <iostream>
#include <stdexcept>

using std::cin;
using std::cout;
using std::endl;
using std::istream;

istream &func(istream &);

int main()
{
	cout << "请输入一些整数,按CTRL+Z结束:" << endl;
	func(cin);
	return 0;
}

istream &func(istream &in)
{
	int i;
	while (in >> i, !in.eof())
	{
		if (in.bad())
			throw std::runtime_error("IO流错误");
		if (in.fail())
		{
			std::cerr << "数据错误,请重试: " << endl;
			in.clear();
			in.ignore(100, '\0');
			continue;
		}
		cout << i << endl;
	}
	in.clear();
	return in;
}

若想了解istream类的成员函数ignore()的用法,点击这里

测试用例及分析

输入:

10 20 30

输出:

在这里插入图片描述

分析:

  1. 主函数创建一个cin对象,读入数据“10 20 30”,cin传递至func函数的形参in
  2. “>>”操作符抽取出in对象中的第一个数10,将10写入变量i中,写入时未发生错误,输出i,此时in对象中剩余数据为“20 30”
  3. 再次循环,“>>”操作符抽取中in对象的第一个数据20,将20写入变量i中,写入时未发生错误,输出i,此时in对象中剩余数据为“30”
  4. 重复上述过程,输出in对象中的最后一个数30
  5. in对象中的数据全部读完后,再读入新的数据,重复上述过程,直到遇到文件结束符(windows系统中CTRZ+Z代表文件结束符)

输入:

10 20 30a123456

输出:

在这里插入图片描述

分析:

  1. 输出10、20、30的过程与前面描述的类似
  2. 30输出完毕后,in对象中剩余数据为“a123456”
  3. 当再次进入循环时,in对象依旧向int型对象i中写入数据,但是由于数据类型不匹配,in的failbit标志位发生改变,进入第二个if语句,输出错误信息,然后将in对象状态位置为合法状态,执行in.ignore语句后,in对象中的数据被全部忽略(需要注意的是,当我们输入数据时,会在最后敲个回车,因此in对象的数据中最后一个字符位’\n’)
  4. in对象数据为空,再输入新的数据,重复上述过程

修改代码

in.ignore(2, '\0');//将100改为2

输入:

10 20 30a123456

输出:

在这里插入图片描述

分析:

  1. 输出10、20、30的过程如前所述,此时in对象中的剩余数据为“a123456”
  2. 再次进入循环,in对象的failbit标志位被设置,进入第二个if语句,再将in对象的状态置为合法,再执行ignore函数,越过两个字符,此时in对象中的数据变为“23456”(a和1被越过)
  3. continue,开始执行下一次循环
  4. in对象向变量i中写入数据123456,合法,输出变量i的值
  5. in对象数据为空,再输入数据,重复上述过程

注意

代码中的ignore函数那一行代码不能去掉,如果去掉,当in对象遇到不合法输入,重置标志位,continue,进行下次循环,此时,该非法输入依旧存在,无限循环

关于cin的补充内容,请点击这里

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值