1.cin

C++ 使用cin可以方便的读取键盘输入的字符,例如:

[cpp] view plaincopyprint

//test input   

#include <iostream>                              

int main()                                

{                                         

    using namespace std;  

    const int size = 20;  

    char name[size];  

    char pl[size];//program language   

  

    cout<<"Enter your name:";  

    cin>>name;  

    cout<<"Enter your favorite program language:";  

    cin>>pl;  

    cout<<"Hello "<<name<<", your favorite program language is "<<pl<<endl;  

    return 0;  

}  

首先,每个输入我们只输入一个单词,如下:

cout<<"Enter your name:"; cin.getline(name,size); 

 cout<<"Enter your favorite program language:";

 cin.getline(pl,size);

 cout<<"Hello "<<name<<", your favorite program language is "<<pl<<endl;

cout<<"Enter your name:"; 

 cin.get(name,size).get();

 if (!cin) 

 {

  cin.clear(); 

  while (cin.get()!='\n')

    {

    continue;

    }

 } 

 cout<<"Enter your favorite program language:";

 cin.get(pl,size).get();

 cout<<"Hello "<<name<<", your favorite program language is "<<pl<<endl;

上面的写法有问题,会导致第二个输入没有机会。原因是:当cin读取年龄时,将回车键生成的换行符留存了输入队列中,后面的cin.getline()看到换行符后,将认为是一个空行,并将一个空字符串赋给address数组。解决办法为在cin>>age;后加cin.get();

但如果我们在第一个输入时填写两个以上单词:

可以发现,第二个输入还没来得及响应,就已经都显示出来了。

原因是:cin通过使用空白(空格、制表符和换行符)来定字符串的界。这意味着cin在读取字符数组输入时只读取一个单词,读取该单词后,cin将该字符串放一数组中,并自动结尾添加空字符。另外,cin也没有很好的控件输入的字符数,即输入字符数大于数组大小的情况没有处理。




2.cin.getline()

基于上面的情况,使用cin.getline()读取一行数据。

cin.getline()函数读取整行,它使用通过回车键输入的换行符来确定输入结尾。该函数有两个参数。第一个参数是用来存储输入行的数组的名称,第二个参数是要读取的字符数(包括空字符),cin.getline()成员函数在读取指定数目的字符或遇到换行符时停止读取

如下:

[cpp] view plaincopyprint?

cout<<"Enter your name:";  

cin.getline(name,size);  

cout<<"Enter your favorite program language:";  

cin.getline(pl,size);  

cout<<"Hello "<<name<<", your favorite program language is "<<pl<<endl;  

现在再来获得多个单词的输入:

发现就正常了。需要注意的是,cin.getline()丢弃了换行符。




3.cin.get()

get()函数有好几种变体,其中有一种与getline()完全相同的参数,但该函数不再读取并丢弃换行符(不读取意味着换行符还在输入队列中):

[cpp] view plaincopyprint?

cout<<"Enter your name:";  

cin.get(name,size);  

cout<<"Enter your favorite program language:";  

cin.get(pl,size);  

cout<<"Hello "<<name<<", your favorite program language is "<<pl<<endl;  

cout<<"Enter your name:"; cin.get(name,size); cout<<"Enter your favorite program language:"; cin.get(pl,size); cout<<"Hello "<<name<<", your favorite program language is "<<pl<<endl;

尝试输入:

发现并不好使,原因是由于第一次调用后,换行符将留存输入队列中,因此第二次调用时看到的第一个字符为换行符。因此get认为已经到达行尾,而没有发现任何可读取的内容。get()(不带任何参数的变体)可以读取下一个字符(包括换行符)。因此可以:

[cpp] view plaincopyprint?

cin.get(name,size).get();  

cin.get(pl,size).get();  

cin.get(name,size).get(); cin.get(pl,size).get();

即可。

注意:有些C++版本没有不带参数的get()变体。可能有只有char参数的变体。可用下面的代替:

char ch;cin.get(name,size).get(ch);




4.读取空行和其他问题

当getline()或get()读取空行时将如何?一般是下一条输入语句将在前一条结束读取的位置开始读取;但当有空行时,当get()读取空行后将设置失效位(failbit),这意味接下来的输入将被阻断,但可以用下面的命令来恢复输入:cin.clear()    cout<<"Enter your name:";  

[cpp] view plaincopyprint?

cout<<"Enter your name:";    

cin.get(name,size).get();    

if (!cin)  

{  

    cin.clear();  

    while (cin.get()!='\n')  

    {  

        continue;  

    }  

}  

cout<<"Enter your favorite program language:";    

cin.get(pl,size).get();    

cout<<"Hello "<<name<<", your favorite program language is "<<pl<<endl;  

另一个潜在的问题是,输入字符可能比分配的空间长。如果输入行包含的字符数比指定的多,则这get()和getline()将把余下的字符留在输入队列中,而getline()还会设置失效位,并关闭输入。



5.混合输入字符串和数字

[cpp] view plaincopyprint?

int age = 0;  

char address[size] = {0};  

cout<<"Enter your age:";  

cin>>age;  

cout<<"Enter your address:";  

cin.getline(address,size);  

cout<<"your age is "<<age <<", your address is "<<address<<endl;  

  #include<iostream>

  #include<string>

  using namespace std;

  main ()

  {

  string str;

  getline(cin,str);

  cout<<str<<endl;

  }

 

  输入:jkljkljkl

  输出:jkljkljkl

  输入:jkl jfksldfj jklsjfl

  输出:jkl jfksldfj jklsjfl

  和cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数



6、gets()        // 接受一个字符串,可以接收空格并输出,需包含“#include<string>”

  #include<iostream>

  #include<string>

  using namespace std;

  main ()

  {

  char m[20];

  gets(m);                       //不能写成m=gets();

  cout<<m<<endl;

  }

  输入:jkljkljkl

  输出:jkljkljkl

  输入:jkl jkl jkl

  输出:jkl jkl jkl

  类似cin.getline()里面的一个例子,gets()同样可以用在多维数组里面:

  #include<iostream>

  #include<string>

  using namespace std;

  main ()

  {

  char m[3][20];

  for(int i=0;i<3;i++)

  {

  cout<<"\n请输入第"<<i+1<<"个字符串:"<<endl;

  gets(m[i]);

  }

  cout<<endl;

  for(int j=0;j<3;j++)

  cout<<"输出m["<<j<<"]的值:"<<m[j]<<endl;

  }

  请输入第1个字符串:

  kskr1

  请输入第2个字符串:

  kskr2

  请输入第3个字符串:

  kskr3

  输出m[0]的值:kskr1

  输出m[1]的值:kskr2

  输出m[2]的值:kskr3

  自我感觉gets()和cin.getline()的用法很类似,只不过cin.getline()多一个参数罢了;

  这里顺带说明一下,对于本文中的这个kskr1,kskr2,kskr3的例子,对于cin>>也可以适用,原因是这里输入的没有空格,如果输入了空格,比如“ks kr jkl[回车]”那么cin就会已经接收到3个字符串,“ks,kr,jkl”;再如“kskr 1[回车]kskr 2[回车]”,那么则接收“kskr,1,kskr”;这不是我们所要的结果!而cin.getline()和gets()因为可以接收空格,所以不会产生这个错误;




7、getchar()   //接受一个字符,需包含“#include<string>”

  #include<iostream>

  #include<string>

  using namespace std;

  main ()

  {

  char ch;

  ch=getchar();                        //不能写成getchar(ch);

  cout<<ch<<endl;

  }

  输入:jkljkljkl

  输出:j

  //getchar()是C语言的函数,C++也可以兼容,但是尽量不用或少用