本文用于自行复习,若有错误请及时指正
目录
我们首先要了解一下两个基本概念:
文件结束符:一种表示文件结束的特殊标记(CTRL+Z表示键盘输入的文件结束符)
文件结束标记:一种判断文件是否结束的标记,用宏定义EOF(end of file)表示
文件结束标记一般用于字符流输入的判断(其他类型一般不用)
用于字符输入的流成员函数
cin.get()
从一个输入流中读取一个字符并返回该字符
char ch = cin.get();
cout << ch;
//输入一个字符并按回车,打印输入的字符
注意cin.get()函数是会读取回车的(相比较而言单纯使用cin就不读回车,而是把回车当作结束输入的标志),用以下代码可以验证:
char ch = cin.get();
cout << ch;
ch = cin.get();
cout << ch;
//此时如果输入字符s+回车,则输出s+一个空行,也就是回车也被读取并输出
如果使用上面这段代码,但是输入了一个庞大的字符串(长度超过了这里可以读取的两个),那么cin.get()函数只会读取第一和第二个字符,后面的不会被正常读取。这也解释了为什么第一段代码输入字符+回车只打印字符,而不是像第二段一样输出一个空行。
那问题就来了。如果想要使用 cin.get() 不断输入并打印整个字符串,使用cin.get()每次只能读取一个字符怎么办呢?那么可以使用 while 循环读入,代码如下:
char ch;
while((ch=cin.get())!='\n')
cout<<ch;
cout<<endl;
这时输入一个字符串,cin.get() 函数会一个个字符判断并读入,然后再 while 循环里输出,直到遇到回车(\n)。这是一个当型循环所以自然回车虽然被读取,但不会被执行输入操作。
cin.get (字符变量)
使用方法及呈现和cin.get()相同,只是不使用返回值,而是使用字符常量(可以理解为输入的字符会给字符常量储存)。这个函数返回cin(流对象自身)。
char ch;
cin.get(ch);
cout<<ch;
//输入一个字符并按回车,输出该字符(用法同cin.get())
特别注意的就是这个函数一般情况下不使用返回值,也不能把返回值用!=或==等逻辑符号和一般字符进行比较,下面的代码会出错:
char ch;
while(cin.get(ch)!='\n')
cout<<ch;
cout<<endl;
//这段代码编译报错
报错显示如下:
当while循环条件判断为 cin.get(ch)!=EOF等,同样编译错误(无法进行比较)。
cin.get (字符数组,字符个数n,终止字符ch)
从输入流中读取 n-1 个字符,若遇到终止字符ch,则提前结束读取进程。
char chs[10];
cin.get(chs,10,'*');
//即读取的储存在字符数组chs中,最多读取9个字符,遇到'*'提前结束
cout<<chs<<endl;
代码使用如上,输出结果参考下表:
输入 | 输出 |
abcdefghijklmn(字符个数>10) | abcdefghi |
abcde(字符个数小于10) | 等待继续输入... |
abcd*efghm(中间出现终止字符) | abcd |
这个函数使用有两个注意点:
- 如果输入的字符串足够长且中间没有终止字符,则会读取n-1个(不是n个)
- 终止字符不会被读入
同时如果不需要终止字符,第三个参数可以省略:
char chs[10];
cin.get(chs,10);
//省略第三个参数,不报错,不报warning,正常运行,没有终止字符限制
cout<<chs<<endl;
关于第三个参数的问题,我们进一步做讨论:
如果终止字符不省略,且不是回车,那么如果输入字符个数小于限制且中间没有终止字符,按回车会不断等待继续输入。
如果终止字符省略,那么默认为回车,字符个数少于限制按回车则停止读取并执行输出操作。
还有一个函数 cin.getline(三个参数),使用方法和cin.get(三个参数)相似,不同点如下一一列举:
- getline遇到终止字符后将终止字符读取,而get不读取
- (未满遇回车)当多个相连,getline和get都把回车当作普通字符读入至满,下一个get从上次结束位置后一个字符开始继续读取,而getline不继续读取
与字符输入有关的其他成员函数
cin.eof ()
判断是否遇到了文件结束符EOF,返回逻辑值(注意:遇到EOF为真)
使用时多放在 while 条件判断中(即当还没遇到文件结束符时.....操作)
char ch;
while(!cin.eof()){
if((ch=cin.get())!='\n')
cout.put(ch);
}
cin.peek ()
返回输入流中的下一个字符(但是不读取),如果遇到文件结束符就返回EOF。
cin.putback ()
将字符常量/变量插入到输入流头部,常与 cin.get() 等连用。一个cin.putback代码如下:
char ch;
ch=cin.get(); //get一次
cin.putback('H'); //putback一次
while((ch=cin.get())!='\n')
cout.put(ch);
//输入abc则输出Hbc
当只有一个 cin.putback() 时,只会替换输入流的第一个字符(如运行上代码输入abc,a被H替换,输出Hbc)。需要注意的是以上代码中 cin.get() 和 cin.putback() 个数是一样的,且都只有一个。下面我们将讨论两者个数不同且有多个的情况:
首先是两个个数相同但有多个的情况:
char ch;
ch=cin.get();
ch=cin.get(); //get两次
cin.putback('H');
cin.putback('a'); //putback两次
while((ch=cin.get())!='\n')
cout.put(ch);
//输入abc则输出iHc
这里可以看到当两者个数相同且都是多个时,原输入流将会“按照顺序”执行这些putback,也就是说后面的putback会替换前面的,继而把之前putback的替换“顶到后面去”。如上端代码,运行输入abc,输出 iHc,就是依次执行替换的结果。
但是当 cin.get() 和 cin.putback() 个数不相同时便会导致问题的出现:
char ch;
ch=cin.get(); //get一次
cin.putback('H');
cin.putback('a'); //putback两次
while((ch=cin.get())!='\n')
cout.put(ch);
//vs2019输入abc则输出iHbc
//如果使用dev编译器,则输出abc后光标不断向后跳动
可以看到这里dev和vs2019/2022表现不同(上段代码注释段),当输出时强制类型转换为int型后输出,dev便会看到无数个-1(可以理解为不可预知错误)。
所以在使用时,一定要保证 get 输入的个数和 putback 个数相同,避免可能出现的错误。
cin.ignore (字符个数n,终止字符ch)
跳过n个字符,或遇到终止字符时提前结束跳跃。
当括号内为空时,缺省跳过一个字符,默认终止字符为EOF。