Bootstrap

常用字符输入cin成员函数详解(自行复习用)

本文用于自行复习,若有错误请及时指正

目录

用于字符输入的流成员函数

cin.get()

cin.get (字符变量)

cin.get (字符数组,字符个数n,终止字符ch)

 与字符输入有关的其他成员函数

cin.eof ()

cin.peek ()

cin.putback ()

cin.ignore (字符个数n,终止字符ch)


我们首先要了解一下两个基本概念:

文件结束符:一种表示文件结束的特殊标记(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;
//这段代码编译报错

报错显示如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5ZOI6YeM5pavSGVucnk=,size_20,color_FFFFFF,t_70,g_se,x_16

 当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

这个函数使用有两个注意点:

  1. 如果输入的字符串足够长且中间没有终止字符,则会读取n-1个(不是n个)
  2. 终止字符不会被读入

同时如果不需要终止字符,第三个参数可以省略:

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。

;