cin 可以用于接收输入, 最常见的是从控制台接收. 在刚学习 C++ 的时候经常会用 cin 来接收数据, 这里想要系统的总结一下 cin 的用法, 保证不灌水.
C++ 中的 cin 是一个 istream 对象, 从标准输入中读取数据, 在 iostream 头文件中定义.
流对象不能拷贝或赋值. 此外, 读写一个 IO 对象都会改变其状态, 因此传递和返回的引用都不能是 const 的, 否则无法读写.
cin 的条件状态
IO 流有四种条件状态, 分别用位来控制.
cin.badbit : 001 1 表示系统级错误, 一旦被置为该状态, 流就无法再使用了
cin.eofbit : 010 2 表示流已经读完, 到达尾部了
cin.failbit: 100 4 可恢复错误, 如期望读取数值却读出一个字符等错误, 或者已经到达流的尾部
cin.goodbit: 000 0 可用状态
当一个流遇到数据类型不一致的错误而不可用时, 我们可以使其恢复为有效状态(置换 eof 和 fail 位):
cin.clear( cin.rdstate() & ~cin.failbit & ~cin.badbit ); //cin.rdstate()表示流当前的状态
也可通过调用成员函数查看流的状态, 如:
cin.eof() cin.fail() cin.bad() cin.good() // 相应状态为真则返回 true, 反则为 false
cin 从缓冲区读取数据, 有多种方式, 如操作符>> 函数 getline(),get()等
- >>
- // 演示操作符>> 的用法
- #include <iostream>
- int main() {
- using namespace std;
- char str1[10];
- while(true) {
- cin>> str1;
- cout <<str1 << endl;
- }
- return 0;
- }
现在有个问题就是: cin 中输入的字符数大于数组的长度会出现什么情况?
当遇到类型不一致时, 流处于不可用状态, 若需继续使用这个流, 需恢复流的有效状态.
get
get 用来获取字符还挺好用的, 肯定不会出错.
- // 演示 get 获取字符
- #include <iostream>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <signal.h>
- void catch_signal(int signal) {
- using namespace std;
- switch(signal) {
- case SIGINT:
- cout <<"ctrl + c 被执行了......" << endl;
- exit(-1);
- break;
- }
- }
- int main() {
- using namespace std;
- // 注册中断信号
- signal(SIGINT, catch_signal);
- char c1;
- while(true) {
- cin.get(c1);
- cout << "c1 =" << c1 << endl;
- }
- return 0;
- }
即 get 函数只会从缓冲区中取字符, 而不会过滤掉任何空格换行符等. 其实我这里有个疑惑, 为啥 cin.get(ch)可以只用变量名, 而不用指针.
getline()
getline 读取一行, 以换行符结束, 丢掉换行符.
还可指定读取多少个字符到数组, 读取完后剩余的字符放在流中, 流被置为无效状态, 可以通过置换使他们变有效, 然后继续读取, 见例子.
- #include <iostream>
- int main() {
- using namespace std;
- char str[10];
- // 实际上只从流中读入 9 个字符, 最后一个字符为自动放一个 0
- // getline 遇到换行才结束
- cin.getline(str, 10);
- cout <<str << endl;
- return 0;
- }
cin>> n, 之后使用 getline 会出现空行, 调用 cin.ignore()即可
如果注释掉 cin.ignore(), 输入 2\enter, 输出空行.
不注释, 输入 2\enterA, 输出 A.
因为 cin 有时会以 \ n 作为结束标志, 但它还在缓存区中, 而 getline 以 \ n 为结束标志, 会读取上一次输入得到的 \ n, 得到一个空行.
cin.ignore(1000, '\n')的含义是把缓冲区内从当前字符开始知道'\n'之前字符 (如果有 1000 个的话) 忽略掉, 实际上你这里假设一行不会超过 1000 个字符, 所以含义是忽略一行.
- #include <iostream>
- int main() {
- using namespace std;
- int n;
- // cin 读入了之后会出现空行
- cin>> n;
- // 调用 cin.ignore()可忽略空行
- cin.ignore();
- cout << "n =" << n << endl;
- char str[10];
- cin.getline(str, 10);
- cout << "str =" << str << endl;
- return 0;
- }
来源: http://www.bubuko.com/infodetail-2843824.html