zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Linux三剑客awk命令试题
    Linux综合练习题
    Linux系统用户角色划分
    Linux添加磁盘fdisk命令
    Linux的七种运行级别
    Linux 文件类型
    Linux开机启动程序
    Linux软件安装
    linux运行级别
    Linux /etc目录下的重要配置文件
  • 原文地址:https://www.cnblogs.com/jainszhang/p/10654562.html
Copyright © 2011-2022 走看看