关于C++的输入输出流(cin、sstream和cout)
测试平台g++ 5.4.0和VS2015社区版。
输入输出原理简述
程序的输入都建有一个缓冲区,即输入缓冲区。当一次键盘输入结束时,输入的数据会被自动存入输入缓冲区中等待处理。
相对应的,程序的输出也建有一个缓冲区,即输出缓冲区。
cin和cout
C++提供了两个用于处理输入和输出的预定义对象cin和cout,它们分别是istream类和ostream类的实例,这两个类是在iostream文件中定义的。
为ostream类定义的插入操作符(<<)使得将数据插入到输出流成为可能;
为istream类定义的提取操作符(>>)能够从输入流中提取数据。
cin和cout都是智能对象,能够根据上下文自动将信息从一种形式转换为另一种形式。
cin对象
cin直接从输入缓冲区中读取数据,因此,当缓冲区中有残留数据时,cin会直接取得这些残留数据而不会请求(等待)键盘输入。
同时,从标准输入流中读取数据时,cin会直接丢掉所有排在前面的空白字符(如回车符\r、换行符\n、制表符\t、空格\040等),从第一个非空白符开始读取,而当读取到空白字符时则停止读取,同时丢弃该空白字符(即从输入流中删掉该字符)。
cin.get()
- cin.get 会保留回车符\r,第一次读取输入时停在回车符前,第二次读取输入时会直接读取该回车符,并因此停止。所以注意两次 cin.get 读取字符串间要加一个单独的 cin.get() 拿掉这个回车符\r。
- cin.get(char_name) 可以用来接收字符;
- cin.get(char[], number) 用来接收一行字符串,可以接收空格;
cin.getline()
- 接收一个字符串,可以接收空格并输出;
- 默认形式(回车符结束)会丢掉最后一个回车符。
- 实际上有三个参数: cin.getline(char[], number, endchar); ,分别是字符数组名,接受的字符个数,标识结束字符。其中第三个参数的系统缺省值为'\0'(空字符,即通用的字符串结束符)。
getline()
- 接受一个字符串,可以接收空格并输出,需包含头文件 #include <string> 。
- 参数列表: getline(cin, str_name, endchar); 与上一个较为不同,第一个参数表明输入流,第二个参数是接收字符串,第三个是结束字符。
- 与 cin.getline() 的相同点是:都接收空白字符(回车符、换行符、制表符、空格等),直到结束符前停止。默认形式(回车符结束)都会丢弃掉最后一个回车符。
- gertline() 与 cin.getline() 的最大区别,在于它们接收变量的本质不同:前者是string对象,而后者是char类型数组。
cin.sync()
清空输入缓冲区。
cin.ignore()
同cin.get()一样,可读取(并丢弃)一个字符,方便读取下一个输入字符。
测试代码(C++)
/*三种函数都可以读取输入缓冲区的字符串数据,但是使用情况在一些细节方面会有区别 * 下面以输入结束方式:默认enter结束和指定结束符两种情况做测试分析 * 输入测试样例:abcd(enter)efghijk,输入结束符指定为‘i’ * */ #include <iostream> #include <string> using namespace std; int main() { char ch1, ch2, ch3; char* chs1=new char; char* chs2=new char; string str; cout << "请输入string内容:" << endl; //cin.get //cin.get(chs1,20); //默认形式 cin.get(chs1,20,'i'); //指定形式 cout << chs1 << endl; //默认形式:第一次回车即立刻输出abcd //指定形式:第二次回车立刻输出abcd(enter)efgh ch1=cin.get(); //默认形式:读取回车符 //指定形式:读取‘i’ cout << ch1<<" "<<(int)ch1 << endl; //默认形式输出:回车符及ASCII码值10 //指定形式输出::‘i’及ASCII码值105 //cin.getline //cin.getline(chs2,20); //默认形式 cin.getline(chs2,20,'i'); //指定形式 cout << chs2 << endl; //默认形式:第一次回车即立刻输出abcd //指定形式:第二次回车立刻输出abcd(enter)efgh ch2=cin.get(); //默认形式:第二次回车后读取第一个非空字符(第一个回车符已被丢弃) //指定形式:读取‘j’(丢弃了‘i’???) cout << ch2<<" "<<(int)ch2 << endl; //默认形式输出:'e'及ASCII码值101 //指定形式:‘j’及ASCII码值106 //getline //getline(cin,str); //默认形式 getline(cin,str,'i'); //指定形式 cout << str << endl; //默认形式:第一次回车即立刻输出abcd //指定形式:第二次回车立刻输出abcd(enter)efgh ch3=cin.get(); //默认形式:第二次回车后读取第一个非空字符(第一个回车符已被丢弃) //指定形式:读取‘j’(丢弃了‘i’???) cout << ch3<<" "<<(int)ch3 << endl; //默认形式输出:'e'及ASCII码值101 //指定形式:‘j’及ASCII码值106 return 0; }
sstream
stringstream是C++提供的一种字符串类型的stream,和输入输出流iostream、文件流fstream有类似的操作方式。要使用stringstream,必须先加入头文件 #include <sstream> 。
stringstream 主要用于字符串的分割,可以先用 clear() 以及 str() 将指定字符串输入字符串流中,再利用>>操作符以空白字符为界的特性将字符串分割输出,例如:
string s; stringstream ss; int a, b, c; getline(cin, s); ss.clear(); ss.str(s); ss >> a >> b >> c;
范例
题目描述
输入的第一行有一个数字N,代表接下来有N行数据,每一行数据为个数不确定的整数(N最大为20,每行最大为200字节)。请写一个程序将每行的总和打印出來。
输入:
3
1 2 3
20 17 23 54 77 60
111 222 333 444 555 666 777 888 999
输出:
6
251
4995
代码实现(C++)
#include <iostream> #include <sstream> using namespace std; int main() { string s; stringstream ss; int n, i, sum, a; cin >> n; getline(cin, s); // 读取换行 for (i=0; i<n; i++) { getline(cin, s); ss.clear(); ss.str(s); sum=0; while (1) { ss >> a; if (ss.fail()) break; sum+=a; } cout << sum << endl; } return 0; }
输出部分待补充。。。