C++输入流对象cin

1.cin追根溯源

cin是C++的istream类对象

extern _LIBCPP_FUNC_VIS istream cin;

extern _LIBCPP_FUNC_VIS ostream cout;

extern _LIBCPP_FUNC_VIS ostream cerr;

istream本名为:basic_istream

typedef basic_istream<char>          istream;

basic_istream虚拟继承自basic_ios

class _LIBCPP_TEMPLATE_VIS basic_istream
    : virtual public basic_ios<_CharT, _Traits>
{...}

在basic_istream(istream)类中存在许多重载的操作符和方法:

    basic_istream& operator>>(bool& __n);
    basic_istream& operator>>(short& __n);
    basic_istream& operator>>(unsigned short& __n);
    basic_istream& operator>>(int& __n);
    basic_istream& operator>>(unsigned int& __n);
    basic_istream& operator>>(long& __n);
    basic_istream& operator>>(unsigned long& __n);
...

可以看出,为什么cin>>能够输入那么多种类的变量了,因为在类里面重载了operator >>(...)

此外,cin所属的类还重载了很多其他的函数,例如;get,getline,ignore,read等。其中get,getline也是读取输入流的方法。

2. cin>>操作符

2.1 cin>>基本操作

cin操作是以Enter、Space、Tab这几个作为输入结束条件的。这句话的意思是说,你一次输入过个数字后,cin以Enter/Space/Tab作为单个输入对象的分隔符。结束后最后执行的回车符不会丢失。

例1:

int a,b;
cin>>a>>b;
cout<<a<<endl<<b;

结果如下:
输入:1 2 3(回车)
输出:
1
2 Process finished with exit code 0

此处有2个对象a和b,输入1 2 3 敲下Enter后,a接收到1,遇到空格结束a的取值,并且忽略空格,b接收到了2,遇到空格结束b的取值切忽略空格,余下的留在缓冲区内。若不想过滤掉空白字符,可以用noskipws流进行控制。如果后面还有需要输入的对象,会直接从缓冲区中取,而不会再取键盘的输入

例1:

int a,b;
cin>>noskipws>>a>>b;
cout<<a<<b<<endl;
输出结果:

输入:1 2(回车)
输出:10

变量b接收到了空格字符,输出为0;

2.2 cin>>针对字符、字符数组、字符串的输入

函数原型如下:

operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)//单个字符的输入
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)//字符数组的输入
operator>>(basic_istream<_CharT, _Traits>& __is,
           basic_string<_CharT, _Traits, _Allocator>& __str)//string数据输入

operator>>()函数第二个参数不同。

3.cin.get(...)

int_type get();//获取缓冲区的一个字符,返回该字符的ASCII值  int res=get();
basic_istream& get(char_type& __c)//get接收到单个字符
basic_istream& get(char_type* __s, streamsize __n)//get接收到字符数组
basic_istream<_CharT, _Traits>::get(char_type* __s, streamsize __n, char_type __dlm)//get接收到字符串,在满足指定长度 __n前提下,遇到字符 __dlm结束读取,且不存储该字符

3.1cin.get(char ch)//获取单个字符

用来接收字符,只获取一个字符,可以接收空格,遇回车结束(回车符不会被丢弃)

//例1:空格不会被丢弃
char
a,b; cin.get(a); cin.get(b); cout<<(int)a<<endl; cout<<(int)b<<endl;

输入:1 2 3(回车)
输出:

49//'1'的ASCII值
32//' '空格的ASCII值

//例2:按回车结束后回车符不会被丢弃
char a,b,c;
cin.get(a);
cin.get(b);
cin.get(c);
cout<<(int)a<<endl;
cout<<(int)b<<endl;
cout<<(int)c<<endl;

输入:1(空格)(回车)
输出:

49
32
10//回车符ASCII值

3.2 cin.get(char *s,streamsize n)

用来接收字符串,可以接收空格,遇回车结束,但是缓冲区会保留回车字符

注意:数组的最后一个字符会是‘\0’,设接收字符数目为n,如果输入的字符串大于等于n,则实际接收到的输入是字符串的前面n-1个字符,包括空格(不包括回车,遇到回车就结束了),会自动在后面增加一个‘\0’。

3.3 cin.get(char *s,streamsize n,char ch)

例1:

    char arr[7];
    cin.get(arr,3,'3');
    for(auto &elem:arr)
        cout<<(int)elem<<" ";
    cout<<endl<<arr;

输入:12 3 4(回车)

输出:

49 0 0 0 0 0 0 //ASCII值
12//只要3个字符,'1','2'和'\0'

例2:

    char arr[7];
    cin.get(arr,7,'4');
    for(auto &elem:arr)
        cout<<(int)elem<<" ";
    cout<<endl<<arr;

输入:1234 5(回车)

输出:

49 50 51 0 0 0 0
123//获取7个字符,但是遇到字符‘4’结束取值

4.cin.getline(...)

函数原型如下:

basic_istream& getline(char_type* __s, streamsize __n)//获取一行数据,回车结束
basic_istream& getline(char_type* __s, streamsize __n, char_type __dlm);//获取一行数组,以__dlm结束

注意:实际接收到的要比n少一个,因为最后一个字符为'\0'。接收一个字符串,可以接收空格等,最后一个字符为‘\0’。结束符可以通过设置第三个参数自己设置,默认是回车

4.1 cin.getline(char *s, size n)

方法与cin.get(char*s,size n)一样

4.2 cin.getline(char*, size n, char dlm)

此处主要讲讲使用dlm截取输入流是cin.get和cin.getline不同之处

使用cin.getline按照指定字符截取输入流:

char arr[7];
cin.get(arr,7,'4');
//cin.getline(arr,7,'4');
cout<<endl<<(char)cin.get()<<endl;
cout<<arr<<endl;
输入:12345(回车)
输出:
4
123

使用cin.get按照指定字符截取输入流:

char arr[7];
//cin.get(arr,7,'4');
cin.getline(arr,7,'4');
cout<<(char)cin.get()<<endl;
cout<<arr<<endl;
输入:12345(回车)
输出:
5
123

对比上述两种方法可见:cin.getline截取后,截取的标志字符丢失,但是cin.get则依旧保留在缓存内

5.其他输入方式以及区别

5.1 cin.get和cim.getline的区别

cin.get()回车后回车符保留在缓存内,cin.getline()回车结束后不保留回车符(见代码)

    char arr[7];
    cin.get(arr,7);
//    cin.getline(arr,7);
    cout<<arr<<endl;
    cout<<endl<<cin.get()<<endl;
输入:
1(回车)
输出:
1
10//保留的回车符的ASCII

使用cin.getline(arr,7);
输入:
1(回车)
输出:
1

5.2.getline()

在string中函数原型如下:

getline(basic_istream<_CharT, _Traits>& __is,
        basic_string<_CharT, _Traits, _Allocator>& __str, _CharT __dlm)

用于string类的。使用需包含头文件#include<string>。getline(cin,string s),接收一个字符串,可以接收空格、回车等

与cin.getline()的区别:

  • cin.getline()接收输入字符的数组,getline()是string类型。
  • cin.getline()可以接收空格,但不能接收回车;getline()可以接收空格和回车
  • cin.getline()会在数组结尾是'\0',getline()不会

5.3.gets()

函数声明如下:

#include<stdio.h>
char
*gets(char *);

gets(char *) 可以接收空格,遇回车结束,但是不会在末尾加上'\0'。并且回车符会丢失

    char arr[2];
    gets(arr);
    cout<<arr<<endl;
    for(auto &elem:arr)
        cout<<(int)elem<<" ";
输入:1 (空格)(回车)
输出:
1
49 32//没有'\0'结束符,空格符可以打印
warning: this program uses gets(), which is unsafe.编译器提示使用这种方式不安全

5.4 getchar()

函数声明原型如下:

该函数包含在C的标准输入输出库中<stdio.h>

#include<stdio.h>
int
getchar(void);

用于获取一个字符,返回值是int类型

例:

char ch;
ch = getchar();
cout<<(int)ch<<endl;
输入:(回车)
输出:10//回车的ASCII值

总结:

主要记忆cin>>,cin.get(),cin.getline()就够了,getchar()输入C的库函数,非C++

cin>>:输入时遇到Tab,Space,Enter几个符号时输入结束,且默认丢弃这几个符号,但是可以设置noskipws获得这几个符号。缓冲区数据如果没有取完,则保留等待下一次取。最后执行的回车符不会丢弃。

cin.get():输入时保留Tab,Space,Enter,当遇到Enter时单个对象输入结束,输入结束后回车符不会被丢弃。可输入单个字符,字符数组,还有按指定字符截断输入功能。字符数组最后默认加'\0'

cin.getline():输入时保留Tab,Space,当遇到Enter时单个对象输入结束。最后的回车符会被丢弃。只可以输入字符数组,不能输入单个字符,且必须有参数。字符数组最后默认加'\0'

cin.get():返回一个int类型字符,不会丢掉回车等字符。res = cin.getchar()操作与该函数一致。这两个函数都无参数。

如有问题,欢迎拍砖,共同进步!

转载请注明出处!

参考:

https://www.cnblogs.com/shrimp-can/p/5241544.html

http://www.cnblogs.com/A-Song/archive/2012/01/29/2331204.html

原文地址:https://www.cnblogs.com/jainszhang/p/10654562.html