C++中 cin的深入理解
2017-03-08 15:54
861 查看
C++中的cin是一个 istream对象,从标准输入中读取数据,在iostream头文件中定义。
流对象不能拷贝或赋值。此外,读写一个IO对象都会改变其状态,因此传递和返回的引用都不能是const的,否则无法读写。
条件状态:
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()等
1. >>
根据后面的变量的类型读取数据
读取时结束条件:enter, space, tab
对结束符的处理:丢掉
2. get
输入结束条件:换行符
对结束符处理:不丢掉
#include <iostream>
using namespace std;
int main()
{
char c1, c2;
cin.get(c1);
cin.get(c2);
cout<<c1<<" "<<c2<<endl; // 打印两个字符
cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值
return 0;
}
输入a b,结果c1被赋值为a, c2被赋值为空格。即get函数只会从缓冲区中取字符,而不会过滤掉任何空格换行符等。(可自己运行只输入a和换行符的情况)
测试:输入123,再输入4的结果。cin.get()只是读取字符,即使输入数字,也是char型,再转换为int型。第一次c1,c2被赋值为'1'和'2',此时缓冲区还有一个3和换行符,cin流仍然有效,再次调用cin流,给c1赋值为缓冲区的3,过滤掉换行符,再次调用cin时,缓冲区已经没有字符了,则从键盘读取,提示用户输入,输入4赋值给c2.此时的c1和c2直接是int型的。
123
49 50
49 50
4
3 4
3 4
3.getline()
getline读取一行,以换行符结束,丢掉换行符。还可指定读取多少个字符到数组,读取完后剩余的字符放在流中,流被置为无效状态,可以通过置换使他们变有效,然后继续读取,见例子。
4.cin之后使用getline会出现空行,调用cin.ignore()即可
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n;
cin >> n;
cin.ignore(); //如果注释掉
string c;
getline(cin, c);
cout << c << endl;
return 0;
}
如果注释掉cin.ignore(),输入2\enter,输出空行。
不注释,输入2\enterA,输出A。
因为cin有时会以\n作为结束标志,但它还在缓存区中,而getline以\n为结束标志,会读取上一次输入得到的\n,得到一个空行。
流对象不能拷贝或赋值。此外,读写一个IO对象都会改变其状态,因此传递和返回的引用都不能是const的,否则无法读写。
条件状态:
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()等
1. >>
根据后面的变量的类型读取数据
读取时结束条件:enter, space, tab
对结束符的处理:丢掉
#include <iostream> using namespace std; int main() { char str1[10], str2[10]; cin>>str1; cin>>str2; cout<<str1<<endl; cout<<str2<<endl; return 0; }当遇到类型不一致时,流处于不可用状态,若需继续使用这个流,需恢复流的有效状态。
2. get
输入结束条件:换行符
对结束符处理:不丢掉
#include <iostream>
using namespace std;
int main()
{
char c1, c2;
cin.get(c1);
cin.get(c2);
cout<<c1<<" "<<c2<<endl; // 打印两个字符
cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值
return 0;
}
输入a b,结果c1被赋值为a, c2被赋值为空格。即get函数只会从缓冲区中取字符,而不会过滤掉任何空格换行符等。(可自己运行只输入a和换行符的情况)
#include <iostream> int main() { int c1, c2; c1=cin.get(); c2=cin.get(); cout<<c1<<" "<<c2<<endl; // 打印两个字符 cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值 cin >> c1; cin >> c2; cout<<c1<<" "<<c2<<endl; // 打印两个字符 cout<<(int)c1<<" "<<(int)c2<<endl; return 0; }
测试:输入123,再输入4的结果。cin.get()只是读取字符,即使输入数字,也是char型,再转换为int型。第一次c1,c2被赋值为'1'和'2',此时缓冲区还有一个3和换行符,cin流仍然有效,再次调用cin流,给c1赋值为缓冲区的3,过滤掉换行符,再次调用cin时,缓冲区已经没有字符了,则从键盘读取,提示用户输入,输入4赋值给c2.此时的c1和c2直接是int型的。
123
49 50
49 50
4
3 4
3 4
3.getline()
getline读取一行,以换行符结束,丢掉换行符。还可指定读取多少个字符到数组,读取完后剩余的字符放在流中,流被置为无效状态,可以通过置换使他们变有效,然后继续读取,见例子。
#include <iostream> int main() { char str[10]; cin.getline(str,5); cout << str << endl; cout << "read state: " << cin.rdstate() << endl; cin.clear(cin.rdstate() & ~cin.failbit); cout << "read state: " << cin.rdstate() << endl; cin.getline(str,5); cout << str << endl; return 0; }
4.cin之后使用getline会出现空行,调用cin.ignore()即可
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n;
cin >> n;
cin.ignore(); //如果注释掉
string c;
getline(cin, c);
cout << c << endl;
return 0;
}
如果注释掉cin.ignore(),输入2\enter,输出空行。
不注释,输入2\enterA,输出A。
因为cin有时会以\n作为结束标志,但它还在缓存区中,而getline以\n为结束标志,会读取上一次输入得到的\n,得到一个空行。
cin.ignore(1000, '\n')的含义是把缓冲区内从当前字符开始知道'\n'之前字符(如果有1000个的话)忽略掉,实际上你这里假设一行不会超过1000个字符,所以含义是忽略一行
相关文章推荐
- 学习《深入理解C++对象模型》小结
- 对C++ STL iostram 中 cin.get(char* cs,int size,char c='/n') 的理解
- 深入理解C++中的mutable关键字
- 《转》深入理解C++中的mutable关键字
- 更深入一点理解switch语句及c/c++对const的处理
- 深入理解c++中const的奥秘
- 深入理解C++中的mutable关键字
- C++:深入理解sizeof
- 深入理解C++中的mutable关键字
- C/C++——深入理解sizeof
- 深入理解C++中的mutable关键字
- C/C++学习笔记2 - cin深入分析(上) - cin输入操作处理(原创)
- 更深入一点理解 switch 语句 及 c/c++ 对 const 的处理
- 深入理解c++拷贝构造函数
- 深入理解C++中的mutable关键字
- 对C++ STL iostram 中 cin.get(char* cs,int size,char c='/n') 的理解
- 惭愧,直到今天才对“数据类型字节对齐”有个深入的了解,对以前读书时学习的知识没有深刻理解啊 C/C++学习 C/C++学习 漫漫人生,澎湃的经历不断促使改变自己,永恒不变的是一颗骄傲的心!
- 深入理解C++中的mutable关键字
- 深入理解C++对象模型-对象的内存布局,vptr,vtable
- 更深入一点理解switch语句及c/c++对const的处理