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

  • 相关阅读:
    android 多线程
    Uva 10881 Piotr’s Ants 蚂蚁
    LA 3708 Graveyard 墓地雕塑 NEERC 2006
    UVa 11300 Spreading the Wealth 分金币
    UVa 11729 Commando War 突击战
    UVa 11292 The Dragon of Loowater 勇者斗恶龙
    HDU 4162 Shape Number
    HDU 1869 六度分离
    HDU 1041 Computer Transformation
    利用可变参数函数清空多个数组
  • 原文地址:https://www.cnblogs.com/jainszhang/p/10654562.html
Copyright © 2011-2022 走看看