关于C++的输入用法
核心模式编码用太多,被ACM模式搞懵了,特地总结一下
读取单个字符
读入一个字符,可以连续读入,例如:cin > a;
或者cin > a > b;
值得注意的是:
1、 cin
可以忽略多个读入之间的空格和回车,比如需要读入a
和b
,那么输入1(空格)(空格)(回车)(回车)2(空格)(空格)3 (空格)4(回车)
,最后依旧读入a=1, b=2
,也就是说需要的字符没有填完之前(此处是两个),会忽略所有的空格和回车。当填完之后,忽略之后所有不是回车的字符,遇到第一个回车结束。
2、 如果数组之前有值,例如:char str[10] = {'a','c','d','e','f','g','h','i'}; cin.getline(str, 5);
此时直接cout << str
会输出cin
读入的值,但是数组后面部分的值仍然存在,也就是cin
读入的值会对数组进行部分覆盖。由于char型数组直接cout数组名,相当于输出字符串,此时可以理解为数组第一个元素被替换成输入的字符串
3、 cin
会读取缓存区的字符,例如需要读入a
和b
,输入1(空格)(空格)(回车)(回车)2(空格)(空格)3 (空格)4(回车)
(上面的输入),此时会读入a=1, b=2
,可以认为是正常的输入,是需要的数据。但是不论执行多少代码之后,例如此时需要读入c
和d
,那么cin
会将缓存区中的数据直接读入,忽略所有的回车和空格,也就是c
和d
会读到之前的3
和4
,并非我们想要的读入。因此使用cin之前,一定记得清空缓存区 cin.sync();
,但是在vs中使用cin.sync();
并不能清空缓存区,需要用到cin.ignore(1024, '\n');
。
清空缓冲区方式详见 C++中清空缓冲区的方法:cin.sync()
:清除输入缓冲区全部的内容;cin.clear()
:用于更改cin的状态标示符。cin在接收到错误的输入的时候,会设置状态位good。如果good位不为1,则cin不接受输入,直接跳过。如果下次输入前状态位没有改变那么即使清除了缓冲区数据流也无法输入。cin.ignore(a, ch)
:从输入缓冲区中提取字符,提取的字符被忽略,不被使用。每抛弃一个字符,都要计数和比较字符,如果计数值达到a或者被忽略的字符是ch,则cin.ignore()
函数终止执行。默认参数是a=1
,即仅忽略缓冲区中的第一个字符。
getline的用法
getline
有两种不同的形式,一种是头文件<iostream>
中的输入流成员函数;一种是头文件<string>
中的普通函数;<iostream>
中的输入流成员函数getline
,函数定义为:
getline(_Elem* _Str, streamsize _Count)
getline(_Elem* _Str, streamsize _Count, _Elem _Delim)
需要定义一个char
型数组来接受输入,例如:
#include <iostream>
#include <istream>
char* str[10];// char* str[10] = "abcd"; char str[] = "abcd"; char str[10] = "";
cin.getline(str, 4);
值得注意的是:
1、 字符数组的长度需要大于或等于实际输入的长度,如果小于则会出错。也就是说如果函数中需要输入5个元素,但是数组长度只有3,同时实际只输入2个元素,那么并不会报错。
2、 读入的元素个数包括空格,并且最后一个会是‘\0’
,遇到(回车)
结束读入。
3、 如果需要读入5个元素,但是只提供3个然后输入回车,那么只会接收3个并且不会报错。
4、 如果需要读入5个元素,但是提供10个然后输入回车,那么只会接收前4个(包含'\0'
)并且不会报错。
<string>
中的输入流成员函数getline
,函数定义为:
getline(basic_istream&& _Istr, basic_string& _Str, const _Elem _Delim)
getline(basic_istream&& _Istr, basic_string& _Str)
getline(basic_istream& _Istr, basic_string& _Str, const _Elem _Delim)
getline(basic_istream& _Istr, basic_string& _Str)
需要定义一个string
来接收输入,例如:
#include <iostream>
string str;//string str = ""; string str = "abcd";
getline(cin, str);
值得注意的是:
1、这里与<iostream>
里的cin.getline()
不同,getline()
读入的值会完全覆盖字符串,也就是如果定义string str = "abcdefg";
,然后输入123
,那么字符串的长度只有3。
2、getline
会读取缓存中的回车,也就是用过getline
之后缓存里并有残留回车,但是cin和cin.getline()
不会。也就是说先用cin
再用getline
会导致getline
读到回车直接结束,但是使用getline
之后再次使用getline
不会,也就是说缓存中没有回车。