博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

cin.get和cin.getline

Posted on 2012-09-14 13:01  子水  阅读(1059)  评论(0)    收藏  举报

分为三种情况来看:
1)输入的字符串不超过限定大小
        get(str,Size):读取所有字符,遇到'\n'时止,并且将'\n'留在输入缓冲区中,其将被下一个读取输入的操作捕获,影响该输入处理;
        getline(str,Size):读取所有字符,遇到'\n'时止,并且将'\n'直接从输入缓冲区中删除掉,不会影响下面的输入处理。


2)输入的字符数超出限定的大小
        get(str,Size):读取Size-1个字符,并将str[Size-1]置为'\0',然后将剩余字符(包括'\n')留在输入缓冲区中,这些字符将被下一个读取输入的操作捕获,影响该输入处理;
        getline(str,Size):读取Size-1个字符,并将str[Size-1]置为'\0',剩余字符(包括'\n')留在输入缓冲区中,随即设置cin实效位(即if(!cin)的判断为真),关闭输入。其后的所有输入都无法得到任何东西,当然也无法得到输入缓冲区中剩余的字符串。但如果象本例一样用clear()重置cin,其后的输入便可用并会得到遗留在输入缓冲区中的字符。


3)输入一个空行(即直接回车)
        get(str,Size):str将得到'\0',并设置cin实效位,关闭输入,但回车依然留在输入缓冲区中,因此如果我们用clear()重置cin,其下一个读取输入的操作将捕获'\n';
        getline(str,Size):str将得到'\0',并将'\n'删除掉,不置实效位,不关闭输入。所以对于cin.getline来说空行是合法的输入,且不会影响下面的输入处理。


        至于使用那个更好,可能因人习惯不同而不同,仁者见仁智者见智。对于我们编程来说,总希望能有更好的容错性,即便用户输入了不合理的输入,程序也应该能够 提示并能够重新输入或继续正常处理,而因为用户的输入问题而导致程序错误或其后的所有输入都不可用显然不是我们希望的。使用get(str,Size)和 getline(str,Size),都可能碰到设置失效位,关闭输入的情况,故都是需要考虑到相应的防错处理的。

下面用C++ Plus Primer中第九章内存模型与名称空间中编程练习中的第1题作为示范。注意setgolf函数中的输入操作。

 1 // main.cpp
 2 #include <iostream>
 3 #include "golf.h"
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     golf ann[3];
 9     int i=0;
10     while (i<3)
11     {
12         if(!setgolf(ann[i]))
13         {
14             break;
15         }
16         i++;
17     }
18     for(int k=0; k<=(i-1); k++)
19     {
20         showgolf(ann[k]);
21     }
22 
23     cout<<"Another setgolf test:\n";
24     golf andy;
25     setgolf(andy, "menghao", 100);
26     
27     handicap(andy, 300);
28     
29     showgolf(andy);
30     
31     return 0;
32 } 
33         
 1 // golf.cpp
 2 #include <iostream>
 3 #include "golf.h" 
 4 #include <cstring> 
 5 using namespace std;
 6 
 7 void setgolf(golf &g, const char *name, int hc)
 8 {
 9     strncpy(g.fullname, name, Len); 
10     g.handicap = hc;
11 }
12 
13 int setgolf(golf &g)
14 {
15     cout<<"Enter name: ";
16     if(!cin.get(g.fullname, Len))  //遇到空行,设置cin实效位,关闭输入,但回车依然留在输入缓冲区中
17     {
18         cin.clear();  //用clear()重置cin
19         cin.get();  //下一个读取输入的操作将捕获'\n'
20 
21         return 0; //返回
22     } 
23     
24     cin.get();  //捕获'\n'
25     cout<<"\nEnter handicap: ";
26     cin>>g.handicap;
27     cin.get();  //捕获'\n'
28 
29     return 1;
30 } 
31 
32 void handicap(golf &g, int hc)
33 {
34     g.handicap = hc;
35 }
36 
37 void showgolf(const golf &g)
38 {
39     cout<<"golf fullname: "<<g.fullname<<" handicap: "<<g.handicap<<endl;
40 } 
41 
42 
43      

 

 1 // golf.h
 2 #ifndef GOLF_H_
 3 #define GOLF_H_
 4 
 5 const int Len = 40; 
 6 struct golf
 7 { 
 8     char fullname[Len];
 9     int handicap;
10 };
11 
12 void setgolf(golf &g, const char *name, int hc);
13 
14 int setgolf(golf &g);
15 
16 void handicap(golf &g, int hc);
17 
18 void showgolf(const golf &g); 
19 
20 #endif