【博客开张】C++,输入错误将会发生什么?

本文对比了C++中cin、cin.get()与getline()的功能差异,解析了它们在处理空白字符及换行符时的行为,并讨论了输入错误的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总结。

首先想要讲的是cin, cin.get(), getline()的用处和不同之处。

然后便是通过我最近的编程练习说一下自己对输入时发生错误的理解。

一、输入

1. cin

cin是C++定义在iostream中的一个表示输入程序字符流的一个对象,对应的又cout,它由std修饰。

在我们需要用户输入一些char值、int值等等时,我们经常使用cin。但是当我们的输入内容中包括空格、制表符的话,cin就会出现一些问题。我们应该考虑到cin是如何确定已完成字符串的输入呢?

实际上,cin是通过使用空白(空格、制表符和换行符)来确定字符串的结束位置,这样,当我们在往字符数组中输入时就可能出现问题,例如:

char name[15];
char addr[20];
cout << "Enter your name: ";
cin  >> name;
cout << "Enter your addr: ";
cin  >> addr;
cout << "name: " << name << "addr: " << addr;
当我们用户输入name为 Kobe Bryant,addr任意时,会出现什么情况呢?程序输出的时候,name会是Kobe,而addr会是Bryant!!读者可以尝试一下。

这是因为cin在读取到Kobe Bryant中间的空格时,cin对name数组的输入就结束了,Bryant其实是在往addr数组中输入!!

所以,当我们要读取的输入中有空白时,就要用到istream中提供的一些面向行输入的类成员函数:getline(),get()。

此外还要介绍一下cin的一个特性:

我们知道,C++中用户输入的字符流,会先被储存到系统的缓存中,可以理解为是一个输入流,这个输入流可能还有着上一次输入中留下来的换行符!

cin是如何避免误读这些换行符呢,其实这是cin的一个特性,当cin从输入流(缓存区)中读取到的第一个字符是空白时,cin会忽略并清除它。然后当cin读取成功,并且读取到下一个空白时,cin是不会处理这个空白,任它留在输入流中的,这意味着,下一次读取到的第一个字符仍是空白,这在当我们交替使用cin,getline()时,有时候会出现问题!

2. cin.get(), cin.getline()

这两个是istream中的类定义的面向行的类成员函数,这两个函数都读取一行输入,直到到达换行符。我们先说getline(),get()和它是类似的:

istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
它其实是有两种用法:

cin.getline(name,20,'#')
cin.getline(name,20)
getline(cin,name)
getline的第三个参数的意思就像是隔断符,遇到#号时输入停止,默认的话就是换行符,get的话也是这种用法,现在我们可以说一下它俩的区别:

getline()读取到换行符停止,并将输入流中的换行符丢弃,但是get()会将换行符留在输入流中,就像cin一样,这就导致一个问题,当你连续调用两次cin.get()时,第二次只会读到换行符而停止输入,不能输入你想输入的内容。

幸运的是,get()有另一种变体能够帮助我们解决这个问题。使用不带参数的cin.get()调用可读取下一个字符(即使是换行符),为读取下一行输入做好准备。实际上,这也是get()的通常用法。

cin.get(name, arsize);
cin.get();
cin.get(addr, arsize);
 二、输入错误

首先,当get()和getline()读取空行时,会发生什么呢?

当前,当get()(不是getline)读取空行后,将设置失效位,我们可以这么理解失效位,就是当设置了失效位之后,就会停止之后的输入命令,接下来的输入将被切断,除非清除掉这个失效位,但可以用下面的命令来回复输入:

cin.clear();
另外一个潜在的问题是,输入字符串可能比分配的空间长,如果输入行包含的字符数比指定的多,则getline()和get()将把余下的字符留在输入流中,并且getline()还会设置失效位,并关闭后面的输入。

此外,当输入发生错误,即试图往一个int对象中输入char型时,输入流中也会设置失效位,并关闭接下来的输入,若果想要继续输入,就可以使用clear来回复。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值