cin 订阅
宫颈上皮内瘤变(CIN)是一组与宫颈浸润癌密切相关的癌前病变的统称。包括宫颈不典型增生和宫颈原位癌,反映了宫颈癌发生中连续发展的过程,即由宫颈不典型增生(轻→中→重)→原位癌→早期浸润癌→浸润癌的一系列病理变化。 展开全文
宫颈上皮内瘤变(CIN)是一组与宫颈浸润癌密切相关的癌前病变的统称。包括宫颈不典型增生和宫颈原位癌,反映了宫颈癌发生中连续发展的过程,即由宫颈不典型增生(轻→中→重)→原位癌→早期浸润癌→浸润癌的一系列病理变化。
信息
就诊科室
妇科
常见病因
人类乳头状瘤病毒,吸烟,微生物感染,内源性与外源性免疫缺陷
常见症状
白带增多,白带带血,接触性出血、宫颈肥大,充血,糜烂,息肉等慢性宫颈炎
英文名称
cervicalintraepithelialneoplasia,CIN
CAD二次开发应用背景
收起全文
精华内容
下载资源
问答
  • C++输入cin详解

    2020-07-30 03:25:22
    输入原理:程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次...正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入。
  • 1、cin cin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出流的对象,也是...
  • 以下是对cin.get()和cin.getline()的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
  • c++中cin用法总结

    2020-07-19 11:29:26
    本文主要对c++中cin用法进行了总结,希望对你的学习有所帮助。
  • 主要介绍了C++ cin.getline用法及C++ getline()的两种用法,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • cin 、cout 基本说明:  cin代表标准输入设备,使用提取运算符 “>>” 从设备键盘取得数据,送到输入流对象cin中,然后送到内存。  cin是输入流,cout是输出流,重载了”>>”、”<<“运算符,包含在头文件...
  • 超时原因没加上 ios::sync_with_stdio(false); cin.tie(NULL); 我真傻,真的,我单知道语言不...因为C++为了兼容c,cin和cout要与stdio同步,中间会有一个缓冲,所以导致cin,cout语句输入输出缓慢,把它置为false就
  • cin和cout提速

    2021-01-03 17:28:37
    在主函数main开头加入一下两句,可以让cin和cout速度大幅度增加: #include int main() { ios::sync_with_stdio(false); cout.tie(NULL); return 0; } 直观感受一下加了这两句对C++读入的性能提升(貌似比用scanf...
  • 处理cin输入int错误.c

    2020-12-25 22:30:37
    处理cin输入int错误.c
  • 1、cin 2、cin.get() 3、cin.getline() 4、getline() 5、gets() 6、getchar() 附:cin.ignore(); cin.get()//跳过一个字符,例如不想要的回车,空格等字符 1、cin>>  用法1:最基本,也是最常用的用法,输入一个数字:...
  • 在做acm一些题时,经常出现 数据集超大造成 cin读入过多 超时的情况。 这是因为在c++中cin,cout虽然方便但是效率低。 是因为先把要输出的东西存入缓冲区,再输出,导致效率降低,而这段语句可以来打消iostream的...
  • 详解C++ cin.getline函数

    2020-12-16 22:44:56
    cin 虽然可以使用 cin 和 >> 运算符来输入字符串,但它可能会导致一些需要注意的问题。 当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读...
  • 易语言cin源码

    2020-07-22 11:25:20
    易语言cin源码,cin,GetProcAddress,LoadLibrary
  • cin

    2017-09-18 21:31:17
    第一次搞cin,真是搞昏人了,现在逐渐开始明白是什么东东,一起探讨一下吧!  首先大家要知道cin是怎么一回事,为什么要有? 在C中,输入输出要用printf和scanf,这是2个很麻烦的东西,因为在输入数据的同时还要说明...
    第一次搞cin,真是搞昏人了,现在逐渐开始明白是什么东东,一起探讨一下吧! 
    
    首先大家要知道cin是怎么一回事,为什么要有?


    在C中,输入输出要用printf和scanf,这是2个很麻烦的东西,因为在输入数据的同时还要说明数据的类型,如果输入数据较多,那就很麻烦了,所以我们的C++搞了两个更爽的东西cout和cin,来替换它们.首先我们先了解一下这两个东西的来处,它们是来自C++的一个类库叫 " iostream".
    iostream是由istream(输入类)和ostream(输出类)派生.所以在iostream中就有了输入和输出的相关对象:
    1,cin,表示标准输入(standard input)的istream类对象.cin使我们可以从设备读取数据.
    2,cout,表示标准输出(standard output)的ostream类对象.cout使我们可以向设备输出或者写数据.
    3,cerr(暂时还没试过,先别理吧)
    暂时先介绍那么多,这里我主要想说的是cin.get()和cin.getline(),cin.clear(),cin.sync()等的用法.


    首先看看cin.get(),它是一个读取单个字符的方法.


    字符变量=cin.get();相当于cin.get(字符变量);


    #include <iostream> 
    using namespace std; 


    int main() 

            char cstr;
             cstr=cin.get();          //读取单个字符,在屏幕输入,也相当于cin.get(cstr);
             cout<<cstr<<endl;  //输出刚刚载入的单个字符
            system("pause"); 
    }


    运行程序后,一切正常:
    输入:a    输出:a


    但当我们输入的不只一个英文字符时,那又会如何呢?
    输入:abcd         输出:a


    由此可知,它只能读取第一个字符,但如果我们把程序修改成:


    int main() 

            char cstr;
            char bstr;
             cstr=cin.get();        //读取单个字符,在屏幕输入
            bstr=cin.get();  
             cout<<cstr<<bstr<<endl;  //输出刚刚载入的单个字符
            system("pause"); 
    }


    我们再输入:abcd    最后输出了:ab
    既然cin.get()是读取第一个字符,那bstr为什么不也是a呢?
    其实原理是这样的:
    在cin这个对象里,有一个储存字符的流,可以想象成缓冲区,但事实上是cin里封装的一个东西.当我们在程序上输入字符后,对象cin获得了我们输入的字符,例如获得abcd,然后再通过.get()把流里面的第一个字符去掉,赋给cstr,这时,cin里储存的流的数据为bcd,而cstr则获得了a.当我们再次运行bstr=cin.get();时,同理把cin里流的数据的b拿出来给了bstr,此后,cin里面的流的数据为cd,而bstr则为b,所以最后输出时,便能输出ab了.


    还有个补充,究竟什么时候才输入数据呢?我们可以再通过上面的代码进行尝试,我们输入单个字母'a',然后按回车,发现并没有输出数据,而是再等待一次输入数据,我们再输入字母'b',按回车后便输出ab了.相信到这里,大家都应该明白了,因为当我们第一次输入a后,通过cstr=cin.get();使cin里的流没有数据,清空了.所以到第二次要再赋给bstr值时,它找不到数据,要重新再输入数据.由此来看可以知道,当cin里的流数据清空时,便需要重新输入才能赋值.而cin.get()还有个用法:


    int main() 

            char cstr;
            char bstr;
             cstr=cin.get();        //读取单个字符,在屏幕输入
            cin.get();
            bstr=cin.get();  
             cout<<cstr<<bstr<<endl;  //输出刚刚载入的单个字符
            system("pause"); 
    }


    程序中有3个cin.get(),所以我们尝试输入:abc.   发现输出了:ac
    由此能知道,当空回调cin.get();时,cin.get便自动在cin中的流数据中删除一个字母,起了一个删除作用.


    对cin.get()有了一定了解之后,对cin.getline()的学习就可以更快了,原理是一致的,但是cin.getline()则是获取一整行文本.以下是cin.getline()原形:
    getline(char *line,int size,char='/n')
    第一个就是字符指针,第二个是字符长度,第三个1行的结束标识符.


    int main() 

            char cstr[200];
            cin.getline(cstr,sizeof(str));     //第三个参数不输入,默认回车为结束标识符
             cout<<cstr<<endl;                //输出
            system("pause"); 
    }


    这样我们输入一堆英文或数字,然后按回车,就会输出一行刚刚输出的东西了.接下来.我们讨论第三个参数的作用.


    int main() 

            char cstr[200];
            cin.getline(cstr,sizeof(str),'X');     //我们以单个英文字母'X'作为终止标识符
             cout<<cstr<<endl;                     //输出
            system("pause"); 
    }


    当我们输入一大堆东西,例如
    输入: kkkkkkk(回车)              输出: kkkkkkk(回车)                        
               bbbbbbb(回车)                     bbbbbbb(回车)       
               lllllX                                          lllll


    这样X便成了终止符,其原理和cin.get一样.或许我们可以像cin.get那样尝试一下:


    int main() 

            char cstr[200];
            char bstr[200];
            cin.getline(cstr,sizeof(str),'X');     //我们以单个英文字母'X'作为终止标识符
            cin.getline(bstr,sizeof(btr),'a');
             cout<<"第一行是:"<<cstr<<endl;                     //输出
            cout<<"第二行是:"<<bstr<<endl;  
            system("pause"); 
    }


    我们输入:kkkkkkkkk(回车)                                        输出:第一行是:kkkkkkkkk(回车) 
                     oooooooooX(回车)                                                              ooooooooo(回车)
                     bbbbbbbbba(回车)                                                第二行是:(回车)
                                                                                                                   bbbbbbbbb


    在这里,我在不厌其烦地说一下原理,如果刚刚cin.get()原理看懂的可以跳过.
    首先,我们第一次getline会把X前面的字符赋给cstr,然后从cin里的数据流删除,标识符X也删除了,所以输出的cstr如上所示.当我们第二次运行getline时,此时cin里的数据流为(回车)bbbbbbbbba,回车也是一个字符,事实上在数据流里用"/n"表示,接着就按照原来第一次的方法,把标识符'a'前面的字符赋给bstr,然后再删除字符号及标识符.所以输出结果如上.


    接下来我们谈谈cin.clear的作用,第一次看到这东西,很多人以为就是清空cin里面的数据流,而实际上却与此相差很远,首先我们看看以下代码:


    #include <iostream> 
    using namespace std; 


    int main() 

            int a; 
            cin>>a; 
            cout<<cin.rdstate()<<endl; 
            if(cin.rdstate() == ios::goodbit)
    {
    cout<<"输入数据的类型正确,无错误!"<<endl; 
                 } 
            if(cin.rdstate() == ios_base::failbit) 
            { 
                    cout<<"输入数据类型错误,非致命错误,可清除输入缓冲区挽回!"<<endl; 
            } 
            system("pause"); 
    }


    我们定义要输入到的变量是整型,但如果我们输入了英文字母或者汉字,那就会发生错误,cin里有个方法能检测这个错误,就是cin.rdstate();
    当cin.rdstate()返回0(即ios::goodbit)时表示无错误,可以继续输入或者操作,若返回4则发生非致命错误即ios::failbit,则不能继续输入或操作.而cin.clear则可以控制我们此时cin里对这个问题的一个标识.语发如下:
    cin.clear(标识符);
    标识符号为:


    goodbit 无错误
    Eofbit 已到达文件尾
    failbit 非致命的输入/输出错误,可挽回
    badbit 致命的输入/输出错误,无法挽回 
    若在输入输出类里.需要加ios::标识符号
    通过cin.clear,我们能确认它的内部标识符,如果输入错误则能重新输入.结合真正的清空数据流方法cin.sync(),请看下例:


    #include <iostream> 
    using namespace std; 


    int main() 

            int a; 
            while(1) 
            { 
                    cin>>a; 
                    if(!cin)            //条件可改写为cin.fail() 
                    { 
                            cout<<"输入有错!请重新输入"<<endl; 
                            cin.clear(); 
                             cin.sync();   //清空流
                    } 
                    else 
                    { 
                            cout<<a; 
                            break; 
                    } 
            } 
            system("pause"); 
    }


    上面的cin默认参数为0,即无错误,正常操作.当我们输入英文字母'k'时,它的状态标识改为fail(即1),即错误,用cout对用户输出信息,再用cin.clear让错误标识改回为0,让我们可以继续输入,再清空流数据继续输入.如果我们没有了cin.clear,则会进入死循环,其过程为我们输入了英文字母,它的状态标识便为fail,当运行到条件判断时,便总是回到错误的条件表示里,并且我们再也没办法输入,因为错误的表示关闭了cin,所以会进入死循环.


    ---------------------------------------------------------------------


    自己再添加一句:如果输入错误,则再也输入不进去,须用clear.而sync用于清除当前输入缓冲区中的内容。



    #include <iostream>


    int main()
    {
     using namespace std;
        
     int a; 
     cin >> a;
     cout << a <<endl;
     cin >> a ;
     cout <<a <<endl;
     cin.clear();
     cin.sync();  // 可以将cin.clear();cin.sync();  不同时注释掉试一下就知道了
     cin >> a;
     cout <<a <<endl;


    return 0;


    }
    展开全文
  • C++中cin的用法详细

    2020-08-25 07:50:20
    主要介绍了C++中cin的用法详细,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • cin详解

    千次阅读 2015-08-14 22:37:40
    输入原理: 程序的输入都建有一个缓冲区...正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入 #include using namespace std; int main() {

    输入原理
    程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入

    #include <iostream>
    using namespace std;
    int main()
    {
       char str1[10], str2[10];
       cin>>str1;
       cin>>str2;
       cout<<str1<<endl;
       cout<< str2 << endl;
       return 0;
    }

    测试:

    abcd efgh

    输出:

    abcd
    efgh

    【分析】第一次读取字符串时遇到空格则停止了,将abcd读入str1,并舍弃了空格,将后面的字符串给了第二个字符串。这证明了cin读入数据遇到空格结束;并且丢弃空格符;缓冲区有残留数据,读入操作直接从缓冲区中取数据。

    cin.get(数组名,长度,结束符)

    Get characters
    Extracts characters from the stream, as unformatted input:

    (1) single character
    Extracts a single character from the stream.
    The character is either returned (first signature), or set as the value of its argument (second signature).
    (2) c-string
    Extracts characters from the stream and stores them in s as a c-string, until either (n-1) characters have been extracted or the delimiting character is encountered: the delimiting character being either the newline character (‘\n’) or delim (if this argument is specified).
    The delimiting character is not extracted from the input sequence if found, and remains there as the next character to be extracted from the stream (see getline for an alternative that does discard the delimiting character).
    A null character (‘\0’) is automatically appended to the written sequence if n is greater than zero, even if an empty string is extracted.
    (3) stream buffer
    Extracts characters from the stream and inserts them into the output sequence controlled by the stream buffer object sb, stopping either as soon as such an insertion fails or as soon as the delimiting character is encountered in the input sequence (the delimiting character being either the newline character, ‘\n’, or delim, if this argument is specified).
    Only the characters successfully inserted into sb are extracted from the stream: Neither the delimiting character, nor eventually the character that failed to be inserted at sb, are extracted from the input sequence and remain there as the next character to be extracted from the stream.

    The function also stops extracting characters if the end-of-file is reached. If this is reached prematurely (before meeting the conditions described above), the function sets the eofbit flag.

    Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to true). Then (if good), it extracts characters from its associated stream buffer object as if calling its member functions sbumpc or sgetc, and finally destroys the sentry object before returning.

    The number of characters successfully read and stored by this function can be accessed by calling member gcount.
    Parameters
    c
    The reference to a character where the extracted value is stored.
    s
    Pointer to an array of characters where extracted characters are stored as a c-string.
    If the function does not extract any characters (or if the first character extracted is the delimiter character) and n is greater than zero, this is set to an empty c-string.
    n
    Maximum number of characters to write to s (including the terminating null character).
    If this is less than 2, the function does not extract any characters and sets failbit.
    streamsize is a signed integral type.
    delim
    Explicit delimiting character: The operation of extracting successive characters stops as soon as the next character to extract compares equal to this.
    sb
    A streambuf object on whose controlled output sequence the characters are copied.
    Return Value
    The first signature returns the character read, or the end-of-file value (EOF) if no characters are available in the stream (note that in this case, the failbit flag is also set).

    All other signatures always return *this. Note that this return value can be checked for the state of the stream (see casting a stream to bool for more info).

    Errors are signaled by modifying the internal state flags:

    flagerror
    eofbitThe function stopped extracting characters because the input sequence has no more characters available (end-of-file reached).
    failbitEither no characters were written or an empty c-string was stored in s.
    badbitError on stream (such as when this function catches an exception thrown by an internal operation).When set, the integrity of the stream may have been affected.

    Multiple flags may be set by a single operation.

    If the operation sets an internal state flag that was registered with member exceptions, the function throws an exception of member type failure.

    其中结束符为可选参数,读入的字符个数最多为(长度-1)个,结束符规定结束字符串读取的字符,默认为ENTER
    若要读取字符,直接cin.get(char ch)或ch=cin.get()即可
    读取字符的情况:
    输入结束条件:Enter键
    对结束符处理:不丢弃缓冲区中的Enter
    cin.get() 与 cin.get(char ch)用于读取字符,他们的使用是相似的,
    即:ch=cin.get() 与 cin.get(ch)是等价的。

    #include <iostream>
    using namespace std;
    int main()
    {
      char c1, c2;
       cin.get(c1);
       cin.get(c2);
        cout<<c1<<" "<<c2<<endl; // 打印两个字符
        cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值
        return 0;
    }

    测试一输入:
    a[Enter]
    输出:
    a

    97 10

    【分析】会发现只执行了一次从键盘输入,显然第一个字符变量取的’a’, 第二个变量取的是Enter(ASCII值为10),这是因为该函数不丢弃上次输入结束时的Enter字符,所以第一次输入结束时缓冲区中残留的是上次输入结束时的Enter字符!

    测试二输入:

    a b[Enter]

    输出:
    a
    97 32

    【分析】显然第一个字符变量取的’a’, 第二个变量取的是Space(ASCII值为32)。原因同上,没有丢弃Space字符。
    读取字符串的情况:

    输入结束条件:默认Enter键(因此可接受空格,Tab键),可在第三个参数上自定义结束符

    对结束符处理:丢弃缓冲区中的Enter

    #include <iostream>
    using namespace std;
    int main ()
    {
      char ch, a[20];
      cin.get(a, 5 , 'd');
      cin>>ch;
      cout<<a<<endl;
      cout<<(int)ch<<endl;
      return 0;
    }

    测试一输入:
    12345[Enter]
    输出:
    1234

    53

    【分析】第一次输入超长,字符串按长度取了”1234”,而’5′仍残留在缓冲区中,所以第二次输入字符没有从键盘读入,而是直接取了’5′,所以打印的ASCII值是53(’5′的ASCII值)。

    测试二输入:

    12d45[Enter]

    输出:

    12

    d

    【分析】第二次输出为d,说明自定义结束符时不丢弃缓冲区中的结束符

    cin.getline()

    Get line
    Extracts characters from the stream as unformatted input and stores them into s as a c-string, until either the extracted character is the delimiting character, or n characters have been written to s (including the terminating null character).

    The delimiting character is the newline character (‘\n’) for the first form, and delim for the second: when found in the input sequence, it is extracted from the input sequence, but discarded and not written to s.

    The function will also stop extracting characters if the end-of-file is reached. If this is reached prematurely (before either writing n characters or finding delim), the function sets the eofbit flag.

    The failbit flag is set if the function extracts no characters, or if the delimiting character is not found once (n-1) characters have already been written to s. Note that if the character that follows those (n-1) characters in the input sequence is precisely the delimiting character, it is also extracted and the failbit flag is not set (the extracted sequence was exactly n characters long).

    A null character (‘\0’) is automatically appended to the written sequence if n is greater than zero, even if an empty string is extracted.

    Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to true). Then (if good), it extracts characters from its associated stream buffer object as if calling its member functions sbumpc or sgetc, and finally destroys the sentry object before returning.

    The number of characters successfully read and stored by this function can be accessed by calling member gcount.

    This function is overloaded for string objects in header : See getline(string).
    Parameters
    s
    Pointer to an array of characters where extracted characters are stored as a c-string.
    n
    Maximum number of characters to write to s (including the terminating null character).
    If the function stops reading because this limit is reached without finding the delimiting character, the failbit internal flag is set.
    streamsize is a signed integral type.
    delim
    Explicit delimiting character: The operation of extracting successive characters stops as soon as the next character to extract compares equal to this.
    Return Value
    The istream object (*this).

    Errors are signaled by modifying the internal state flags:

    flagerror
    eofbitThe function stopped extracting characters because the input sequence has no more characters available (end-of-file reached).
    failbitEither the delimiting character was not found or no characters were extracted at all (because the end-of-file was before the first character or because the construction of sentry failed).
    badbitError on stream (such as when this function catches an exception thrown by an internal operation).When set, the integrity of the stream may have been affected.

    Multiple flags may be set by a single operation.

    If the operation sets an internal state flag that was registered with member exceptions, the function throws an exception of member type failure.

    也可以这样说:
    cin.getline(数组名,长度,结束符) 大体与 cin.get(数组名,长度,结束符)类似。
    区别在于:
    cin.get()当输入的字符串超长时,不会引起cin函数的错误,后面的cin操作会继续执行,只是直接从缓冲区中取数据。但是cin.getline()当输入超长时,会引起cin函数的错误,后面的cin操作将不再执行。

    #include <iostream>
    using namespace std;
    int main ()
    {
      char ch, a[20];
      cin.getline(a, 5);
      cin>>ch;
      cout<<a<<endl;
      cout<<(int)ch<<endl;
      return 0;
    }

    测试输入:
    12345[Enter]
    输出
    1234
    -52

    【分析】与cin.get()的例子比较会发现,这里的ch并没有读取缓冲区中的5,而是返回了-52,这里其实cin>>ch语句没有执行,是因为cin出错了!

    cin.peek()

    Peek next character
    Returns the next character in the input sequence, without extracting it: The character is left as the next character to be extracted from the stream.

    If any internal state flags is already set before the call or is set during the call, the function returns the end-of-file value (EOF).

    Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to true). Then (if good), it reads one character from its associated stream buffer object by calling its member function sgetc, and finally destroys the sentry object before returning.

    Calling this function sets the value returned by gcount to zero.
    Parameters
    none
    Return Value
    The next character in the input sequence, as a value of type int.

    If there are no more characters to read in the input sequence, or if any internal state flags is set, the function returns the end-of-file value (EOF), and leaves the proper internal state flags set:

    flagerror
    eofbitNo character could be peeked because the input sequence has no characters available (end-of-file reached).
    failbitThe construction of sentry failed (such as when the stream state was not good before the call).
    badbitError on stream (such as when this function catches an exception thrown by an internal operation).When set, the integrity of the stream may have been affected.

    Multiple flags may be set by a single operation.

    If the operation sets an internal state flag that was registered with member exceptions, the function throws an exception of member type failure.

    大致意思是:
    该调用形式为cin.peek() 其返回值是一个int型,其返回值是指针指向的当前字符,但它只是观测,指针仍停留在当前位置,并不后移。如果要访问的字符是文件结束符,则函数值是EOF(-1)。

    #include <iostream>
    using namespace std;
    int main () {
        char c;
        int n;
        char str[256];
        cout << "Enter a number or a word: ";
        c=cin.peek();
        if ( (c >= '0') && (c <= '9') )
        {
            cin >> n;
            cout << "You have entered number " << n << endl;
        }
        else
        {
            cin >> str;
            cout << " You have entered word " << str << endl;
        }
        return 0;
    }

    cin.ignore()
    Extract and discard characters
    Extracts characters from the input sequence and discards them, until either n characters have been extracted, or one compares equal to delim.

    The function also stops extracting characters if the end-of-file is reached. If this is reached prematurely (before either extracting n characters or finding delim), the function sets the eofbit flag.

    Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to true). Then (if good), it extracts characters from its associated stream buffer object as if calling its member functions sbumpc or sgetc, and finally destroys the sentry object before returning.

    Parameters

    n
    Maximum number of characters to extract (and ignore).
    If this is exactly numeric_limits::max(), there is no limit: As many characters are extracted as needed until delim (or the end-of-file) is found.
    streamsize is a signed integral type.
    delim
    Delimiting character: The function stops extracting characters as soon as an extracted character compares equal to this.
    Note that the delimiting character is extracted, and thus the next input operation will continue on the character that follows it (if any).
    If this is the end-of-file value (EOF), no character will compare equal, and thus exactly n characters will be discarded (unless the function fails or the end-of-file is reached).

    Return Value
    The istream object (*this).

    Errors are signaled by modifying the internal state flags:

    flagerror
    eofbitThe function stopped extracting characters because the input sequence has no more characters available (end-of-file reached).
    failbitThe construction of sentry failed (such as when the stream state was not good before the call).
    badbitError on stream (such as when this function catches an exception thrown by an internal operation).When set, the integrity of the stream may have been affected.

    Multiple flags may be set by a single operation.

    If the operation sets an internal state flag that was registered with member exceptions, the function throws an exception of member type failure.

    cin.ignore(a,ch)方法是从输入流(cin)中提取字符,提取的字符被忽略(ignore),不被使用。每抛弃一个字符,它都要计数和比较字符:如果计数值达到a或者被抛弃的字符是ch,则cin.ignore()函数执行终止;否则,它继续等待。它的一个常用功能就是用来清除以回车结束的输入缓冲区的内容,消除上一次输入对下一次输入的影响。比如可以这么用:cin.ignore(1024,’\n’),通常把第一个参数设置得足够大,这样实际上总是只有第二个参数’\n’起作用,所以这一句就是把回车(包括回车)之前的所以字符从输入缓冲(流)中清除出去。

    #include <iostream>
    using namespace std;
    void main()
    {
        int a,b,c;
        cout<<"input a:";
        cin>>a;
        cin.ignore(1024, '\n');
        cout<<"input b:";
        cin>>b;
        cin.ignore(1024, '\n');
        cout<<"input c:";
        cin>>c;
        cout<<a<<"\t"<<b<<"\t"<<c<<endl;
    }

    如果没有cin.ignore(),可以一次输入3个数,用空格隔开就好了。。可是非常不美观。。这样才是我们想要的。

    如果cin.ignore()不给参数,则默认参数为cin.ignore(1,EOF),即把EOF前的1个字符清掉,没有遇到EOF就清掉一个字符然后结束,会导致不正确的结果,因为EOF是文件结束标识呵。

    #include<iostream>  
    using   namespace   std;  
    
    void main()  
    {  
        char   str1[30],str2[30],str3[30];  
        cout   <<   "请输入你的姓名:";  
        cin>>str1;  
        cout<<"请输入你的住址:";  
        cin.ignore();  
        cin.getline(str2,30,'a');  
        cout   <<   "请输入你的籍贯:";  
        cin.ignore();  
        cin.getline(str3,30);  
        cout<<str3;  
    }  

    如果在地址那里输入bcdabcd那么此时流里面剩的是bcd\n,此时cin.ignore();吃掉的就是b了,这是流里还剩下cd\n直接交给cin.getline(str3,30);应为有个\n所以这里getline就直接返回 .
    cin.putback()
    Put character back
    Attempts to decrease the current location in the stream by one character, making the last character extracted from the stream once again available to be extracted by input operations.

    Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to true). Then (if good), it calls sputbackc(c) on its associated stream buffer object (if any). Finally, it destroys the sentry object before returning.

    If the call to sputbackc fails, the function sets the badbit flag. Note that this may happen even if c was indeed the last character extracted from the stream (depending on the internals of the associated stream buffer object).

    Calling this function sets the value returned by gcount to zero.

    Parameters
    c
    Character to be put back.
    If this does not match the character at the put back position, the behavior depends on the particular stream buffer object associated to the stream:
    In string buffers, the value is overwritten for output stream buffers, but the function fails on input buffers

    In file buffers, the value is overwritten on the intermediate buffer (if supported): reading the character again will produce c, but the associated input sequence is not modified

    Other types of stream buffer may either fail, be ignored, or overwrite the character at that position.
    Return Value
    The istream object (*this).

    Errors are signaled by modifying the internal state flags:

    flagerror
    eofbit-
    failbitThe construction of sentry failed (such as when the stream state was not good before the call).
    badbitEither the internal call to sputbackc failed, or another error occurred on the stream (such as when the function catches an exception thrown by an internal operation, or when no stream buffer is associated with the stream).When set, the integrity of the stream may have been affected.

    Multiple flags may be set by a single operation.

    If the operation sets an internal state flag that was registered with member exceptions, the function throws an exception of member type failure.

    putback函数调用形式为cin.putback(ch),其作用是将前面用get或者getline函数从输入流中读取的字符ch返回到输入流,插入到当前指针的位置,供后面读取。
    读出来之后,再放回去,让别人也可以读 :

    譬如输入了 ‘m ‘;
    cin> > a;
    cin> > b;
    此时a= ‘m ‘,b等待你的输入
    cin> > a;
    cin.putback(a);
    cin> > b
    此时a和b都可以读回来a= ‘m’,b= ‘m’

    using namespace std;
    int main () {
        char c;
        int n;
        char str[256];
        cout << "Enter a number or a word: ";
        c = cin.get();
        if ( (c >= '0') && (c <= '9') )
        {
            cin.putback (c);
            cin >> n;
            cout << "You have entered number " << n << endl;
        }
        else
        {
            cin.putback (c);
            cin >> str;
            cout << " You have entered word " << str << endl;
        }
        return 0;
    }

    cin.good()
    Check whether state of stream is good
    Returns true if none of the stream’s error state flags (eofbit, failbit and badbit) is set.

    This function behaves as if defined as:

    bool ios::good() const {
      return rdstate() == goodbit;
    }

    Notice that this function is not the exact opposite of member bad, which only checks whether the badbit flag is set.

    Whether specific error flags are set, can be checked with member functions eof, fail, and bad:

    这里写图片描述
    eofbit, failbit and badbit are member constants with implementation-defined values that can be combined (as if with the bitwise OR operator).
    goodbit is zero, indicating that none of the other bits is set.
    Parameters
    none
    Return Value
    true if none of the stream’s state flags are set.
    false if any of the stream’s state flags are set (badbit, eofbit or failbit).

    检查输入是否出错,参数无,返回值bool类型:没有出错返回true,否则返回false

    cin.clear()
    Set error state flags
    Sets a new value for the stream’s internal error state flags.

    The current value of the flags is overwritten: All bits are replaced by those in state; If state is goodbit (which is zero) all error flags are cleared.

    In the case that no stream buffer is associated with the stream when this function is called, the badbit flag is automatically set (no matter the value for that bit passed in argument state).

    Note that changing the state may throw an exception, depending on the latest settings passed to member exceptions.

    The current state can be obtained with member function rdstate.
    Parameters
    state
    An object of type ios_base::iostate that can take as value any combination of the following state flag member constants:
    这里写图片描述
    eofbit, failbit and badbit are member constants with implementation-defined values that can be combined (as if with the bitwise OR operator).
    goodbit is zero, indicating that none of the other bits is set.
    Return Value
    none

    清除输入流的错误信息,无返回值

    cin.eof()
    Check whether eofbit is set
    Returns true if the eofbit error state flag is set for the stream.

    This flag is set by all standard input operations when the End-of-File is reached in the sequence associated with the stream.

    Note that the value returned by this function depends on the last operation performed on the stream (and not on the next).

    Operations that attempt to read at the End-of-File fail, and thus both the eofbit and the failbit end up set. This function can be used to check whether the failure is due to reaching the End-of-File or to some other reason.

    Parameters
    none

    Return Value
    true if the stream’s eofbit error state flag is set (which signals that the End-of-File has been reached by the last input operation).
    false otherwise.

    检查是否读到文件结尾,返回值为bool类型

    cin.fail()

    cin.bad()

    展开全文
  • 易语言cin源码-易语言

    2021-06-13 14:43:32
    易语言cin源码
  • cin和scanf在使用时的注意事项
  • cincin.get()、cin.getline()、getline()的区别

    万次阅读 多人点赞 2018-05-14 15:51:30
    测试平台g++ 5.4.0和VS2015社区版。...正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入。 比如下面的例子: voidtest_i...

    测试平台g++ 5.4.0和VS2015社区版。

    输入原理简述:

    程序的输入都建有一个缓冲区,即输入缓冲区。每次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数直接从输入缓冲区中取数据(cin读取数据是从第一个非空白字符开始到下一个空白字符结束)。正因为cin函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数会直接取得这些残留数据而不会请求键盘输入。

      比如下面的例子:

    void test_input()  
    {  
        string str;  
        cout<<"cin的测试:"<<endl;  
        cin>>str;  
        cout<<str<<endl;  
        cin>>str;  
        cout<<str<<endl;  
    }  


            由于cin在遇到空格/tab时,就会停止读取,所以如果我在第一次输入时,利用空格隔开两个字符串,那么cin在第一次取的时候,只会读取前一个字符串,到空格结束,此时缓冲区还保留着前面输入的第二个字符串,那么第二次cin就会直接从缓冲区取残留数据,而不会请求输入。

           当然对于以上的情况,也有解决的方案,那就是在第二次调用cin>>str之前通过cin.sync()来清空输入缓冲区,看一下下面的例子,此处不赘述:

    void test_input()  
    {  
        string str;  
        cout<<"cin的测试:"<<endl;  
        cin>>str;  
        cin.sync();  
        cout<<str<<endl;  
        cin>>str;  
        cout<<str<<endl;  
    }  


      各种输入方法简介:

            1、cin>>

            根据cin>>sth 中sth的变量类型读取数据,这里变量类型可以为int,float,char,char*,string等诸多类型。这一输入操作,在遇到结束符(Space、Tab、Enter)就结束,且对于结束符,并不保存到变量中。注意:最后一个enter也在缓冲区。

    void test_input()  
    {  
        char ch;
        char ch1[10],ch2[10];  
        cout<<"输入两个字符串:"<<endl;  
        cin>>ch1;  
        cin>>ch2;  
        cout<<"两个字符串分别为:"<<endl;  
        cout<<ch1<<endl;  
        cout<<ch2<<endl;  
        cin.get(ch);
        cout << (int)ch << endl; //输出10,为最后一个enter输入
    }  


    2、cin.get(字符数组名,接收长度,结束符)

    其中结束符意味着遇到该符号结束字符串读取,默认为enter,读取的字符个数最多为(长度 - 1),因为最后一个为'\0'。要注意的是,cin.get(字符数组名,接收长度,结束符)操作遇到结束符停止读取,但并不会将结束符从缓冲区丢弃。cin.get函数有如下几种声明:

    int get();
    istream& get(char& c);
    istream& get(char* s, streamsize n);
    istream& get(char* s, streamsize n, char delim);
    istream& get(streambuf& sb);
    istream& get(streambuf& sb, char delim);

    (1)接收一个字符ch=cin.get()或cin.get(char ch),二者等价,看两个例子

    cin.get()存在的基本目的,我认为就是为了从c移植到c++的时候,直接用cin.get()代替getchar(),也正因因此,cin.get()的返回值跟其它cin.get成员函数返回cin对象不同,跟getchar()一样返回int。所以cin.get()和C语言的getchar()没什么区别。

     

    void test_input()  
    {  
        char ch1,ch2;  
        cout<<"请输入两个字符:"<<endl;  
        cin.get(ch1);//或ch1 = cin.get();  
        cin.get(ch2);  
        cout<<ch1<<" "<<ch2<<endl;  
        cout<<(int)ch1<<" "<<(int)ch2<<endl;  
    }  
    

    来看几组测试:

    • 连续输入ab[enter],结果正常,ch1,ch2分别读取了a、b,将其输出,然后在输出其ASCII值。要注意的是,以上输入并读取后,缓冲区中依然存在[Enter]没有被删除。

     

    • 输入a[Space]b[Enter],结果在输出时,只看到了a,输出ASCII值时候分别为97 32(空格的ASCII值),这就说明cin.get()并不会舍弃Space,依然会将其读取进去,并加以显示等操作。 

     

    • 输入a[Enter],输出见下图。在输出a之后,第二次的输出产生了换行的效果,而输出的第二个ASCII值为10(Enter的ASCII值),这就进一步响应了前面说到的cin.get()遇到结束符并不会将之删除。  

     

    (2)接收一定长度的字符串cin.get(字符数组名,接收长度,结束符),结束符为可选参数,默认为Enter,可以接受Space 、Tab,对于结束符的处理要注意,结束符并不会丢掉,同样看几个例子。

    • 对于如下代码,所做的操作时,在不遇到enter时最多读入(6-1)=5个字符到ch2中,然后读入下一个字符到ch1中,显示ch2,ch1以及其ASCII码值。附上几组测试:  
    void test_input()  
    {  
        char ch1,ch2[10];  
        cout<<"请输入字符串:"<<endl;  
        cin.get(ch2,6);//在不遇到结束符的情况下,最多可接收6-1=5个字符到ch2中,注意结束符为默认Enter  
        cin.get(ch1);//或ch1 = cin.get();  
        cout<<ch2<<endl;  
        cout<<ch1<<"\n"<<(int)ch1<<endl;  
    }  

     

    • 输入:zifuchuan[Enter],由于输入长度大于(6-1)=5,所以会首先读入“zifuc”到ch1,此时“huan”仍在缓冲区,当执行cin.get(ch1)会直接从缓冲区读入h,而不需要申请从键盘输入,看一下结果,符合分析。

    • 输入:zifu[Enter],此时输入长度小于5就遇到了默认结束符Enter,则ch2中只读入“zifu”,要注意的是,输入缓冲区里面的Enter还在,所以接下来要读入的ch1的内容将是Enter,而输出时将看到换行,ASCII码值为10,见下图

    • 输入:zi fuchuan[Enter],注意中间的空格,cin.get()对空格并不敏感,依然会读入,故而ch2读入的是“zi fu”,ch1读入的是c

    假如:

    #include <iostream>
    using namespace std;
    
    int main()
    {
    	char ch1, ch2[10];
    	cout << "请输入字符串:" << endl;
    	cin.get(ch2, 13);//在不遇到结束符的情况下,最多可接收13-1=12个字符到ch2中,注意结束符为默认Enter  
    	cin.get(ch1);//或ch1 = cin.get();  
    	cout << ch2 << endl;
    	cout << ch1 << "\n" << (int)ch1 << endl;
    	
    	return 0;
    }

    输入:123456789(enter)

    输出:

    输入:1234567890(enter)

    则VS2015运行报错!因为ch2[10]用cin.get最多接受9个字符,最后一个是'\0'。但g++ 5.4.0正常(说明没有对下标越界做检查)。

     

    还有一点需要注意的是,cin.get(字符数组名,接收长度,结束符),当一开始第一个输入字符(即前面无其他任何字符)就遇到结束符情况下,将不会正常输出,但缓冲区中依然有该结束符。

    例:

    #include <iostream>
    using namespace std;
    
    int main()
    {	
    	char ch[5], ch2;	
    	cin.get(ch, 3); //默认结束符'\n',此处直接(enter)
    	cin.get(ch2);
    	cout << ch2 << ' ' << (int)ch2 << endl; //VS2015 输出-52, g++ 5.4.0 输出0
    	
    	return 0;	
    }

    以上程序如果输入1(enter),将正常输出\n的ASCII码,输出如下:

     

    清除错误标志:

    #include <iostream> 
    using namespace std;
    
    int main()
    {
    	char ch[5], ch2;
    	cin.get(ch, 3); //默认结束符'\n',此处直接(enter)
    	cin.clear(); //清除错误标志
    	cin.get(ch2); 
    	cout << ch2 << ' ' << (int)ch2 << endl;
    
    	return 0;
    }
    

    输出:

    可见结束符依然在缓冲区当中。

    再来一例:

    #include <iostream>
    using namespace std;
    
    int main()
    {	
    	char ch[5], ch2;	
    	cin.get(ch, 3, 'a');// 结束符为'a',直接输入a(enter)
    	cin.get(ch2);
    	cout << ch2 << ' ' << (int)ch2 << endl;
    	
    	return 0;	
    }
    	

    输出:

    如果输入1a(enter),输出如下:

     

    清除错误标志:

    #include <iostream> 
    using namespace std;
    
    int main()
    {
    	char ch[5], ch2;
    	cin.get(ch, 3, 'a');// 结束符为'a',直接输入a(enter)
    	cin.clear(); // 清除错误标志
    	cin.get(ch2);
    	cout << ch2 << ' ' << (int)ch2 << endl;
    
    	return 0;
    }
    
    

    输出:

    可见结束符'a'依然在缓冲区当中。

     

    补充:cin.get(ch2)和ch2 = cin.get()小区别:

    #include <iostream>
    using namespace std;
    
    int main()
    {	
    	char ch[5], ch2;	
    	cin.get(ch, 3, 'a'); //此处输入a(enter)
    	ch2 = cin.get(); //注意与cin.get(ch2)不同
    	cout << ch2 << ' ' << (int)ch2 << endl;
    	
    	return 0;	
    }

     

    (3)cin.get( ),注意此时没有参数,可用于舍弃输入流中的不需要的字符,或者舍弃回车,弥补cin.get(字符数组名,字符数目,结束符)的不足。对(2)中的代码加入一句话cin.get()如下:

    void test_input()  
    {  
        char ch1,ch2[10];  
        cout<<"请输入字符串:"<<endl;  
        cin.get(ch2,6);//在不遇到结束符的情况下,最多可接收6-1=5个字符到ch2中  
        cin.get();//注意:前面两句可以写到一块:cin.get(ch2,6).get();  
        cin.get(ch1);//或ch1 = cin.get();  
        cout<<ch2<<endl;  
        cout<<ch1<<"\n"<<(int)ch1<<endl;  
    }  
    • 前面遇到的一个状况是,输入字符后,其结束符(如默认的Enter)会保留在缓冲区中,当下次读入时,又会再读入,此时就可以用到cin.get()读掉输入缓冲区不需要的字符,如:输入:zi[Enter],由于遇到结束符,所以ch2内容为zi,此时输入缓冲区还存在着[Enter],但cin.get()将其舍弃掉之后,cin.get(ch1)就会申请从键盘输入内容,如下所示:

    3、cin.getline(字符数组名,接收长度,结束符)

    其用法与cin.get(字符数组名,接收长度,结束符)极为类似。cin.get()当输入的字符串超长时,不会引起cin函数的错误,后面若有cin操作,会继续执行,只是直接从缓冲区中取数据。但是cin.getline()当输入超长时,会引起cin函数的错误,后面的cin操作将不再执行。如下代码:

    1. void test_input()  
      {  
          char ch1,ch2[10];  
          cout<<"请输入字符串:"<<endl;  
          cin.getline(ch2,6);//在不遇到结束符的情况下,最多可接收6-1=5个字符到ch2中  
          cin>>ch1;  
          cout<<ch2<<endl;  
          cout<<ch1<<"\n"<<(int)ch1<<endl;  
      }  

       

    •  测试:如下图,输入zifuchuan[Enter],长度大于最大长度5,就会导致cin函数错误,其后既没有像cin.get()一样直接从输入缓冲区直接读数据,也没有从键盘输入。所以此处可以注意,考虑在用cin.getline()时,适度设置其最大接受长度大一点。
    • 假如:
      #include <iostream>
      using namespace std;
      
      int main()
      {
      	char ch1, ch2[6]; // 最多可接收5个,最后一个'\0'
      	cout << "请输入字符串:" << endl;
      	cin.getline(ch2, 8);//在不遇到结束符的情况下,最多可接收8-1=7个字符到ch2中  
      	cin >> ch1;
      	cout << ch2 << endl;
      	cout << ch1 << "\n" << (int)ch1 << endl;
      
      	return 0;
      }

      输入:123456(enter)     VS将会报错,g++正常。说明VS对数组下标进行了检查。

    • cin.get()每次读取一整行并把由Enter键生成的换行符留在输入队列中,然而cin.getline()每次读取一整行并把由Enter键生成的换行符抛弃,比如:
    • #include <iostream>
      using namespace std;
      
      int main() {
      	cout << "Enter your name:";
      	char name[15];
      	//cin.get(name, 15);
      	cin.getline(name, 15);// 输入abc(enter)
      	cout << "name:" << name << endl;
      	char ch;
      	cin.get(ch);// 输入123(enter) 注:因为cin.getline把最后一个换行符丢弃了,所以此处ch读取字符'1'
      	cout << (int)ch << endl;  //输出49  '1'的ASCII码值
      	cout << "\nEnter your address:";
      	char address[15];
      	//cin.getline(address, 15);
      	cin.get(address, 15); //直接读取缓冲区剩余的23 注:cin.get保留最后一个换行符在缓冲区
      	cout << "address:" << address << endl;	
      	cin.get(ch); // 读取缓冲区最后一个换行符
      	cout << (int)ch << endl;
      	cin.get(ch);  // 缓冲区已为空,所以从键盘输入a
      	cout << (int)ch << endl; //输出97  'a'的ASCII码值
      	return 0;
      }

     

    #include <iostream>
    using namespace std;
    
    int main() {
    	cout << "Enter your name:";
    	char name[15];
    	cin.get(name, 15); // 输入abc(enter)
    	//cin.getline(name, 15);
    	cout << "name:" << name << endl;
    	char ch;
    	cin.get(ch); //因为cin.get不会丢弃最后一个换行符,所以此处ch读取换行符
    	cout << (int)ch << endl; //输出10  '\n'的ASCII码值
    	cout << "\nEnter your address:";
    	char address[15];
    	cin.getline(address, 15); //输入123(enter)
    	//cin.get(address, 15);
    	cout << "address:" << address << endl;	
    	cin.get(ch);// 因为cin.getline丢弃最后一个换行符,所以此处重新从键盘输入a(enter)
    	cout << (int)ch << endl; //输出97 'a'的ASCII码值
    	cin.get(ch);   // cin.get不会丢弃最后一个换行符,所以此处读取上一步输入的保留在缓冲区的换行符
    	cout << (int)ch << endl; // 输出10 '\n'的ASCII码值
    	return 0;
    }

     

     

    4、getline(istream is,string str,结束符)

    同样,此处结束符为可选参数(默认依然为enter)。然而,getline()与前面的诸多存在的差别在于,它string库函数下,而非前面的istream流,所有调用前要在前面加入#include<string>。与之对应这一方法读入时第二个参数为string类型,而不再是char*,要注意区别。另外,该方法也不是遇到空白字符(tab, space, enter(当结束符不是默认enter时))就结束输入的,且会丢弃最后一个换行符。

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
    	char ch;
    	string str;
    	cout << "请输入string内容:" << endl;
    	getline(cin, str); //输入:abc(space)(space)d(enter)
    	//getline(cin, str, 'a');	
    	cout << str << endl;
    	cin.get(ch); //因为丢弃了最后一个换行符,所以此处从键盘输入b
    	cout << (int)ch << endl; //输出:98 'b'的ASCII码值
    	return 0;
    }

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
    	char ch;
    	string str;
    	cout << "请输入string内容:" << endl;
    	//getline(cin, str);
    	getline(cin, str, 'a');	//输入:string(enter)strinabc,遇到结束符'a'停止读取
    	cout << str << endl; //输出string(enter)strin
    	cin.get(ch); //将缓冲区中'a'丢弃,读取'a'之后的'b'
    	cout << (int)ch << endl; //输出:98 'b'的ASCII码值
    	return 0;
    }

     

    5、getline和cin.getline区别

    cin.getline()当输入超长时,会引起cin函数的错误,后面的cin操作将不再执行。

    #include <iostream>  
    using namespace std;
    
    int main()
    {
    	char ch, a[20];
    	cin.getline(a, 5);// 此处输入12345(enter)
    	cin >> ch;
    	cout << a << endl;
    	cout << (int)ch << endl;
    	return 0;
    }

    输出:

    这里的ch并没有读取缓冲区中的5,而是返回了-52(VS)/0(g++),这里其实cin>>ch语句没有执行,是因为cin出错了!我们经常会看到程序中会出现cin.clear(),cin.ignore(), cin.fail()等函数。这些函数都是与cin的错误处理有关的。这一节我们来分析一下cin的错误处理机制,并且学习几个重要的函数:cin.fail(), cin.bad(), cin.good(), cin.clear(), cin.ignore()等。程序执行时有一个标志变量来标志输入的异常状态,其中有三位标志位分别用来标志三种异常信息,他们分别是:failbit,eofbit,badbit。

    ios类定义了这四个常量badbit, eofbit, failbit, goodbit,其实这四个标志常量就是取对应标志位的掩码,也即输入的四种异常情况!

     

    以上四个常量在g++对应的取值为:
    ios::badbit    001   输入(输出)流出现致命错误,不可挽回 
    ios::eofbit    010   已经到达文件尾
    ios::failbit   100   输入(输出)流出现非致命错误,可挽回 
    ios::goodbit   000   流状态完全正常, 各异常标志位都为0

    我们可以用输出语句来验证这几个常量的值:
    cout << ios:: failbit << endl;
    cout << ios:: eofbit << endl;
    cout << ios:: badbit << endl; 
    cout << ios:: goodbit << endl;
    g++输出的结果为:

     

    VS下输出:

    【注意】它们不是failbit、badbit、eofbit、goodbit这四个标记位的存贮变量,而是四个标志四种异常状态的常量,其实他们就相当于取对应状态标志位的掩码。如果标志变量为flag,则flag & failbit 就取得fail标志位。

     

    搞清楚了标志位的原理后,我们来看几个关于异常标志的函数:

    1、iostate ios::rdstate()
    取标志变量的值,我们可以用该函数取得整个标志变量的值,再与前面定义的标志位常量相与就可以获得对应标志位的状态。如:

    void TestFlags( ios& x ) // 获得x流的三个标志位状态  
    {  
    cout << ( x.rdstate( ) & ios::badbit ) << endl;  
    cout << ( x.rdstate( ) & ios::failbit ) << endl;  
    cout << ( x.rdstate( ) & ios::eofbit ) << endl;  
    cout << endl;  
    }  

    2、bool ios::fail()const;
    1 or true if rdstate & failbit is nonzero, otherwise 0 or false. (引用msdn)
    其中rdstate即通过rdstate()取得的标识变量的值,与failbit相与,即取得failbit标志位的值,如果结果非零则放回true,否则返回false。即该函数返回failbit的状态,将标志位状态通过bool值返回。

    3、bool ios::bad() const;
    1 or true if rdstate & badbit is nonzero; otherwise 0. (引用msdn)
    与fail()相似。

    4、bool ios::good()const;
    1 or true if rdstate == goodbit (no state flags are set), otherwise, 0 orfalse. (引用msdn)
    改函数取goodbit的情况,即三个标志位都0(即没有任何异常情况)时返回true,否则返回false。

    5、voidios::clear(iostate _State=goodbit);
    该函数用来重置标识变量,_State是用来重置的值,默认为goodbit,即默认时将所有标志位清零。用户也可以传进参数,如:clear(failbit),这样就将标识变量置为failbit(即:001)。
    我们一般是用它的默认值,当cin出现异常,我们用该函数将所有标志位重置。如果cin出现异常,没有重置标志的话没法执行下一次的cin操作。如上一节的程序2的测试二为什么第二次输入操作没有执行?程序8中 cin>>ch 为什么没有执行?都是这个原因!!!
    所以经常在程序中使用 cin.clear(), 为了重置错误标志!

    6、另外还有一个函数 void ios::setstate(iostate_State);
    这个函数也是用来设置标识变量的,但与clear()不同。clear()是将所有标志清零,在置以参数新的标志。而该函数不清零其他的标志,而只是将参数对应的标志位置位。这个函数不是经常使用,这里不再赘述。

    在搞清楚了这几个函数后,对cin输入操作的错误处理就有了比较深的了解了。下面我们回过头来看看上一节程序8的测试,因为第一次用getline()读取字符串超长,所以导致出现异常,大家可以查看一下标志位来验证一下!所以会导致后面的 cin>>ch 语句没有执行。那我们利用前面学习的clear()函数来强制重置错误标志,看看会出现什么情况呢?

    #include<iostream>  
    using namespace std;  
    int main ()  
    {  
    char ch, str[20];  
    cin.getline(str, 5);  
    cout<<"flag1:"<<cin.good()<<endl;   // 查看goodbit状态,即是否有异常  
    cin.clear();                        // 清除错误标志  
    cout<<"flag1:"<<cin.good()<<endl;   // 清除标志后再查看异常状态  
    cin>>ch;   
    cout<<"str:"<<str<<endl;  
    cout<<"ch :"<<ch<<endl;  
    return 0;  
    }  
    


    测试输入:
    12345[Enter]
    输出:
    flag1:0 // good()返回false说明有异常
    flag2:1 // good()返回true说明,clear()已经清除了错误标志
    str:1234
    ch :5
    【分析】程序执行结束还是只执行了一次读操作,cin>>ch还是没有从键盘读取数据,但是与程序8中不同,这里打印了ch的值为'5',而且在cin>>ch之前已经清楚了错误标志,也就是cin>>ch的读操作实际上执行了。这就是前面讲的cin读取数据的原理:它是直接从输入缓冲区中取数据的。此例中,第一次输入"12345",而getline(str, 5)根据参数'5'只取缓冲区中的前4个字符,所以str取的是"1234",而字符'5'仍在缓冲区中,所以cin>>ch直接从缓冲区中取得数据,没有从键盘读取数据!
    也就是当前一次读取数据出错后,如果缓冲区没有清空的话,重置错误标志还不够!要是能将缓冲区的残留数据清空了就好了哦!下面我们再来看一个很重要的函数!

    7、basic_istream&ignore(streamsize _Count = 1, int_type _Delim = traits_type::eof());
    function: Causes a number of elements to be skipped from the current readposition.
    Parameters:
    _Count, The number of elements to skip from the current read position.
    _Delim, The element that, if encountered before count, causes ignore to returnand allowing all elements after _Delim to be read. (引用msdn)

    这个函数用来丢弃输入缓冲区中的字符,第一参数定义一个数,第二个参数定义一个字符变量。下面解释一下函数是怎样执行的:函数不停的从缓冲区中取一个字符,并判断是不是_Delim,如果不是则丢弃并进行计数,当计数达到_Count退出,如果是则丢弃字符退出。例:cin.ignore(5, 'a'); 函数将不断从缓冲区中取一个字符丢弃,直到丢弃的字符数达到5或者读取的字符为'a'。下面我们看个程序例子:

    #include <iostream>  
    using namespace std;
    
    int main()
    {
    	char ch;
    	cin.ignore(5, 'a');
    	cin.get(ch);
    	cout << (int)ch << endl;
    	return 0;
    }

    1.当输入:123456(enter)时,VS和g++都输出54(字符'6'的ASCII码)。如下所示:

    2.当输入:b(enter)b(enter) b(enter) 时,VS和g++都输出10(即最后一个enter的ASCII码)。说明cin.ignore()会读取enter,如下所示:

    3.但当输入:1234(enter)ab(enter)时,VS输出97('a'),g++输出98('b')。

    也就是VS中cin.ignore()将第一个enter读取了,但g++中cin.ignore()未读取第一个enter,而是读取了第一个enter之后的'a'。

    丢弃一个字符:
    我们看看这个函数的默认值,第一个参数默认为1,第二个参数默认为EOF。所以cin.ignore()就是丢弃缓冲区中的第一个字符,这在程序中也是比较常用的!

    #include <iostream>  
    using namespace std;  
    int main()  
    {  
    char c1, c2;  
    cin.get(c1);  
            cin.ignore(); // 用该函数的默认情况,丢弃一个字符,即上次输入结束的回车符  
    cin.get(c2);  
    cout<<c1<<" "<<c2<<endl;   // 打印两个字符  
    cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值  
    return 0;   
    }  

    测试一输入:
    a[Enter]
    b[Enter]
    输出:
    a
    b
    97 98
    【分析】这样程序就正常了!

    清空整个缓冲区:
    其实该函数最常用的方式是这样的,将第一个参数设的非常大,将第二个参数设为'\n',这样就可以缓冲区中回车符中的所有残留数据,因为一般情况下前面输入残留的数据是没有用的,所以在进行新一次输入操作前将缓冲区中所有数据清空是比较合理。
    如:cin.ignore(1024, '\n'); 
    或者:cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 

     

    参考网址:

    1. https://blog.csdn.net/livecoldsun/article/details/25489429

    2.https://blog.csdn.net/xuexiacm/article/details/8101859#commentsedit

    展开全文
  • cin.get()等函数的详细用法总结
  • 主要介绍了C++编程中用put输出单个字符和cin输入流的用法,是C++入门学习中的基础知识,需要的朋友可以参考下
  • 下面小编就为大家带来一篇浅谈c++中的while(cin)问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了C++对cin输入字符的判断及分段函数处理方法,结合实例形式分析了C++输入判断及处理相关操作技巧,需要的朋友可以参考下
  • C++ cin输入流 详细用法

    万次阅读 多人点赞 2016-07-16 17:35:43
    C++ cin输入流 详细用法

    我们来看下下面这段代码:

    #include <iostream>
    #include <vector>
    #include <cstdlib>
    
    int main()
    {
      int num = 0;
      std::vector<int> ivec;
        do {
          std::cout << "please input some numbers:" << std::endl;
          while (std::cin >> num)//一直检测输入流状态知道遇到文件结束符(ctrl+z)或错误输入
        ivec.push_back(num);
          if (ivec.size() == 0)
        std::cout << "Error!" << std::endl;
        } while (ivec.size() == 0);
      system("pause");
      return 0;
    }

    现在我们基于这段代码进行一些讨论:

    运行发现,当第一次输入正确的时候,则运行正确,如果第一次输入错误(例如以Ctrl+z然后按Enter),则程序会进入死循环:
    程序会进入死循环

    分析以下原因:
    首先需要了解cin的用法。C++输入缓冲机制规定当用户键入输入之后按下Enter键,便会将所有刚刚用户输入的一次性全送到缓冲区,而cin便会从输入缓冲区中读取数据。回车标志一次输入的完成,如果数据不够,则会等待用户继续输入;如果数据有多余,则将多余的数据存储在输入流缓冲区中,供下次使用。
    举个例子:

    whilestd::cin >> num)//一直检测输入流状态知道遇到文件结束符(ctrl+z)或错误输入
      std::cout<< num << std::endl;

    这条语句,如果输入一次1 2 3 ,执行结果是:

    1

    2

    3

    执行过程如下:

    第一次运行std::cin >> num的时候,输入缓冲区是空的,当用户输入1 2 3 ctrl+z然后回车,这时候cin读入第一个整数1,然后输出1和换行,下一次执行 std::cin >> num的时候,缓冲区不为空,所以不再要求用户输入,直接读取第二个整数2,然后输出2和换行。以此类推,后面输出3 。

    然后cin检查到文件结束标志ctrl+z,cin>>num返回false,循环退出。

    需要特别注意的一点是:当缓冲区中有残留数据时,cin会直接去读取缓冲区的数据而不会请求键盘输入。重要的是,回车符也会被存在输入缓冲区中。

    有了这些知识,就可以解释前面代码中的现象了。如果第一次没有输入有效字符,以ctrl+z加上回车键结束输入后,回车符会被当成一个字符存入输入缓冲区。循环的时候,到了while(std::cin >> num)的时候,cin读取到文件结束符(Ctrl+z),cin的状态被置位,不再接收输入,所以ivec.size()等于0,程序再次进入下一个循环,由于 cin不再接受输入, `所以程序进入死循环。(之前看别人说是Enter的原因,但其实不是,在cin进行第二次读取之前,cin已经不再接受输入)

    所以我们需要将代码做一点小小的修改:

    int main()
    {
      int num = 0;
      std::vector<int> ivec;
        do {
          std::cout << "please input some numbers:" << std::endl;
          while (std::cin >> num)//一直检测输入流状态知道遇到文件结束符(ctrl+z)或错误输入
        ivec.push_back(num);
        std::cin.clear();//添加这一行。
          if (ivec.size() == 0)
        std::cout << "Error!" << std::endl;
        } while (ivec.size() == 0);
      system("pause");
      return 0;
    }

    修改后的代码运行正常

    运行正常

    代码中添加了std::cin.clear();,这个函数有两个作用:
    i、用来更改cin的状态标示符的,cin在接收到错误的输入的时候,会设置状态位good。如果goodbit位不为0,则cin不接受输入。如果下次输入前状态位没有改变那么即使清除了缓冲区数据流也无法输入。所以当输入流发生错误后,要想再次进行输入,必须添加std::cin.clear()。
    ii、具有清除缓冲区的作用。

    std::cin.ignore()这个函数不具备更改cin状态标识的功能,如果把上面代码中的std::cin.clear()函数换成std::cin.ignore,则程序在第一次输入不正确的情况下仍会进入死循环:
    这里写图片描述


    接着讨论第二个问题,把第二段代码修改以下:

    int main()
    {
      int num = 0, val1 = 0;
      std::vector<int> ivec;
        do {
          std::cout << "please input some numbers:" << std::endl;
          while (std::cin >> num)//一直检测输入流状态知道遇到文件结束符(ctrl+z)或错误输入
        ivec.push_back(num);
        std::cin.clear();
          if (ivec.size() == 0)
        std::cout << "Error!" << std::endl;
        } while (ivec.size() == 0);
        std::cin >> val1;
        std::cout << val1;
      system("pause");
      return 0;
    }

    运行后输入1 2 3 Ctrl+z 然后Enter,直接就这样了:
    这里写图片描述
    程序不会等待你输入,直接输出了val1的初始值0,这是为什么呢?
    前面说过:当缓冲区中有残留数据时,cin会直接去读取缓冲区的数据而不会请求键盘输入。而且重要的是,回车符也会被存在输入缓冲区中。
    程序运行后输入1 2 3 Ctrl+z然后Enter,while(std::cin >> num)一直检测输入流知道cin读取到文件结束符(Ctrl+z),循环结束,1、2、3都会被依次cin读取并从缓冲区中除去,留下一个Enter还在缓冲区中等待输入流,所以执行std::cin >> val1 这个语句的时候,cin会去缓冲区中读取数据,读取到Enter后输入结束,所以cout直接输出val1的初始值0。

    所以我们需要将代码进行以下修改:

    int main()
    {
      int num = 0, val1 = 0;
      std::vector<int> ivec;
        do {
          std::cout << "please input some numbers:" << std::endl;
          while (std::cin >> num)//一直检测输入流状态知道遇到文件结束符(ctrl+z)或错误输入
        ivec.push_back(num);
        std::cin.clear();
          if (ivec.size() == 0)
        std::cout << "Error!" << std::endl;
        } while (ivec.size() == 0);
        std::cin.ignore();//添加这一句
        std::cin >> val1;
        std::cout << val1;
      system("pause");
      return 0;
    }

    在while循环之后添加std::cin.ignore(),在执行std::cin >> val1前,清除缓冲区中的内容,则程序运行正常。

    但这里有产生一个问题,在用户输入的时候多次输入Enter,程序却不会出现输入错误,一直等待着用户输入,直到有正常数据输入:
    这里写图片描述

    这里值得说一下的是,当执行cin语句时,Enter可能会被当成是连续的空格符来处理,也可能被当成是结束符来处理,这个由cin的定义决定,而作为连续的空格则被忽略掉,

    我们可以来测验最前面所说的一下造成程序进入死循环的原因,
    在上面那段代码中std::cin.ignore后面再添加一句while( std::cin >> num );

    这里写图片描述

    如图所示,while(std::cin >> num)在接收到文件结束符后便不再接受输入,直接输出val1、val2的初始值0。如果说是里面残留了一个Enter的原因的话,那val1结束输入有可能,但两个同时结束输入就不太对了吧。
    四个也一样:这里写图片描述

    加了std::cin.ignore()清除掉残留在缓冲区的Enter也不行:
    这里写图片描述

    所以一开始程序进入死循环的原因,是cin读取到文件结束符(Ctrl+z),cin的状态被置位,不再接收输入,所以ivec.size()一直等于0,进入死循环,就是这样。

    以上内容其实可以总结成三点:
    1、当cin接收到错误输入后,其状态会被改变,不再接收输入,只有用cin.clear()将cin的goodbit复位之后,才能正常接收输入。
    2、输入时键入的Enter也会被存储在缓冲区中。
    3、Enter有时候会被读成连续的空格,有时候会被读成结束符,这个由cin自己判断决定。

    展开全文
  • cin后使用getline

    千次阅读 2018-10-18 14:52:02
    getline()用来读取一行数据,但是当getline()前面进行了cin输入的话,getline()会把进行cin输入时行末丢弃的换行符读入,从而造成getline()第一次获得的数据为一空行。 问题: 此时getline()所读入的第一行是空行...
  • [C++] cin.get(),cin.getline(),cin.clear()使用技巧

    千次阅读 多人点赞 2018-11-08 20:22:14
    cin是用于输入的istream类的一个对象使用cin进行输入时,程序将输入视为一系列的字符,然后cin对象才负责将字符转换为其他类型。在输入数据时,可使用cin &amp;amp;gt;&amp;amp;gt; ch、cin.get(ch)、ch = ...
  • cin与cout用法

    2015-11-27 21:50:36
    本文件是对cin和cout一些用法的总结,框图结构,需要用mindjet打开,(同时推介一下mindjet这款工具,很适合代码爱好者总结)。对cin、cout用法迷惑的请进

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,234,581
精华内容 493,832
关键字:

cin