C++从标准输入输出读取字符串
九月份校招开始多了起来,很多公司都有笔试环节。而笔试的编程题很多都需要从标准输入输出流里面读取数据,这里就总结一下怎么从标准流读取字符串,同时也是给自己做个备忘录,免得时间长忘记了。
1、getline()方法
在C++中本质上有两种getline函数:
第一种:在头文件<istream>中,是iostream类的成员函数。
第二种:在头文件<string>中,是普通函数。
第一种在<istream>中定义的getline()函数有以下两种重载形式:
istream& getline (char* s, count n);
istream& getline (char* s, count n, char delim);
作用是: 从istream中读取至多n个字符(包含结束标记符)保存在s对应的数组中。即使还没读够n个字符,如果遇到delim 或 字数达到限制,则读取终止,delim都不会被保存进s对应的数组中。
#include<iostream>
char str[20];
std::cin.getline(str,20);
std::cout << str << std::endl;
在控制台输入123 456,回车,程序输出字符串str的值:123 456
第二种在<string>中定义的getline函数有以下四种重载形式:
istream& getline (istream& is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
istream& getline (istream& is, string& str);
istream& getline (istream&& is, string& str);
用法和上第一种类似,但是形式上不一样,读取的istream是作为参数is传进函数的,读取的字符串保存在string类型的str中。
is:表示输入流,例如 cin,或者文件输入流 fstream。istream&是左值引用,istream&&是右值引用。
str:string类型的引用,用来存储输入流中的流信息。
delim:char类型的变量,所设置的截断字符,默认是’\n’。
#include<string>
string str;
getline(std::cin,str);
输入输出和上面一样。
2、cin对象
使用cin从标准输入读取数据时,除了cin.getline()方法外,通常还会用到的方法有cin>>,cin.get等。
cin>>可以连续从键盘读取想要的数据,以空格、tab或换行作为分隔符,例如:
char str[20];
std::cin >> str;
std::cout << str << std::endl;
不管字符串前面有多少回车和空格,都会被忽略,在控制台输入多个空格后再输入12345,回车,程序输出字符串str的值:12345
但是如果字符串中间有空格或者制表符tab,则读取的内容会截断。例如在控制台输入123 456,回车,程序输出字符串str的值:123
如果想要读取包含空格或者tab等分隔符的一行字符串,可以使用cin.get函数。
cin.get和cin>>一样,既可以读取单个字符,也可以读取字符串。有如下四种常用重载形式:
int cin.get();
istream& cin.get(char& var);
istream& get ( char* s, streamsize n );
istream& get ( char* s, streamsize n, char delim );
char str[20];
std::cin.get(str,20);
std::cout << str << std::endl;
在控制台输入123 456,回车,程序输出字符串str的值:123 456
但是这个方法和cin.getline方法还是有区别的:
cin.get读取一行时,遇到换行符时结束读取,但是不对换行符进行处理,换行符仍然残留在输入缓冲区(cin>>方法也是如此)。cin.getline读取一行字符时,默认遇到’\n’时终止,并且将’\n’直接从输入缓冲区中删除掉,不会影响下面的输入处理。我们做个测试:
char str[20] ;
char s;
std::cin.get(str,20);
std::cin.get(s);
std::cout << str << std::endl;
std::cout << (int)s << std::endl;
还是在控制台输入123 456,回车,程序输出字符串str的值:123 456的同时,还输出了10,因为换行符的ASCII码是10。
所以使用cin>>和cin.get方法读取数据的时候一定要特别小心,因为最后的换行符还留在输入缓冲区里面。再看一个例子:
int num = 0;
std::cin >> num;
char strList[5][20];
for (int i = 0; i < num; i++) {
std::cin.getline(strList[i], 20);
}
for (int i = 0; i < num; i++) {
std::cout << strList[i] << std::endl;
}
我们从第一行读取一个数字n,代表有n个字符串,然后从控制台依次读取n个字符串,并将这n个字符串输出。如果输入:
3
Zhangsan
Lisi
Wangwu
本来应该输出:
Zhangsan
Lisi
Wangwu
但是结果如下图:
输入完第二个字符串并回车之后,就输出了结果,for循环里面不是应该读取3个字符串吗?
原来strList数组已经读取了三个字符串,只是数组里第一个字符串读取的是上一个cin>>num残存的换行符,因此内容为空。
要想实现原来的功能,只需对程序稍微修改一下:
int num = 0;
char c;
std::cin >> num;
cin.get(c);
char strList[5][20];
for (int i = 0; i < num; i++) {
std::cin.getline(strList[i], 20);
}
for (int i = 0; i < num; i++) {
std::cout << strList[i] << std::endl;
}
好了,这就是今天想要跟大家分享的内容,以及cin>>,cin.get方法读取字符串要注意的地方,下篇博客见!