精华内容
下载资源
问答
  • 2022-04-10 01:45:48

     1.cin.getline()函数cin.getline(字符数组名,字符个数,结束标志),结束标志可以省略,碰到回车就会停止。
      cin.getline()可以接收空格,直到碰到回车才停止,所以会读取n-1个元素。

    #include <iostream>
    using namespace std;
    int main() {
      char a[100] ;
    cout<<"输入的值为:"<<end;
        cin.getline(a, 10);
        for(int i = 0; i<10;i++)
        cout << "输出的值:"<<a[i]<< endl;
        return 0;
    }
    

    用户端输入的字符不足给定的元素个数,则只截取用户的元素,如果用户端输入的字符数目大于给定的,则按照给定的数目截取,空格也算在内。

    结果:

    D:\untitled19\cmake-build-debug\untitled19.exe
    输入的值:1 2 3456789
    输出的值:
    1
    
    2
    
    3
    4
    5
    6
    7
    
    
    Process finished with exit code 0
    

    2.(1) getline()函数getline(cin, str)  将输入流保存到str中去,过程中空格也一并接收可读取整行,

    包括前导和嵌入的空格,并将其存储在字符串对象中。

    #include <iostream>
    #include <string> //来导入标准库中的字符串类和相关操作,导入后才能使用string类
    using namespace std;
    int main()
    {
        string name;
        string city;
        cout << "Please enter your name: ";
        getline(cin, name);
        cout << "Enter the city you live in: ";
        getline(cin, city);
        cout << "Hello, " << name << endl;
        cout << "You live in " << city << endl;
        return 0;
    }

    运行结果:

    D:\untitled39\cmake-build-debug\untitled39.exe
     Please enter your name: jan
     Enter the city you live in: Beijing
     Hello, jan
    You live in Beijing
    
    Process finished with exit code 0
    

      (2) 当同时使用cin和getline时,在输入流cin结束后需要清空缓存,否则下一个读入的并不是用户的输入而是一个回车。 例如:

    #include <iostream>
    #include <string> 
    using namespace std;
    int main()
    {
        string c;
        int a;
        cin>>a;
        getline(cin, c);
        cout<<c<<endl;
        return 0;
    }

    运行结果:

    D:\untitled39\cmake-build-debug\untitled39.exe
    5
    
    
    Process finished with exit code 0
    

    输入流赋值给a后,本想通过getline获取c,却没有机会再进行输入了,这是因为cin之后的回车交给了c, 程序结束

     解决方法是插入一个函数用来接收\n,然后再调用自己的getline函数来接收之后的string c;

    测试结果: 

    D:\untitled39\cmake-build-debug\untitled39.exe
    2
    b
    b
    
    Process finished with exit code 0
    

    更多相关内容
  • 下面先看下C++ cin.getline用法,具体内容如下所示: 使用 C++ 字符数组与使用 string 对象还有另一种不同的方式,就是在处理它们时必须使用不同的函数集。例如,要读取一行输入,必须使用 cin.getline 而不是 ...
  • 详解C++ cin.getline函数

    2020-12-16 22:44:56
    cin 虽然可以使用 cin 和 >> 运算符来输入字符串,但它可能会导致一些需要注意的问题。 当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读...
  • 学C++的时候,这几个输入函数弄的有点迷糊;这里做个小结
  • cin.getline()和cin.get()都是对输入的面向行的读取,即一次读取整行而不是单个数字或字符,但是二者有一定的区别。cin.get()每次读取一整行并把由Enter键生成的换行符留在输入队列中,比如: 代码如下:#include ...
  • cin.get()和cin.getline()、getline()和gets()、getchar()的区别
  • 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

    展开全文
  • 这几天开始学的时候,一直对 cincin.get(),cin.getline(),getline() 这四种输入迷迷糊糊的,很容易混淆,敲代码时总会犯一些错,使得代码的运行结果并不使人满意,所以做完这一题后,我准备做一次简单总结,来使...

    一、简述

    这几天开始学的时候,一直对 cin,cin.get(),cin.getline(),getline() 这四种输入迷迷糊糊的,很容易混淆,敲代码时总会犯一些错,使得代码的运行结果并不使人满意,所以做完这一题后,我准备做一次简单总结,来使自己正确掌握目前所学到的这四种输入方法。

    二、题目:

    /*
    	设计一个名为 car 的结构,用它存储下述有关汽车的信息:
    	生产商(存储在字符数组或 string 对象中的字符串)、生产年份(整数)。
    	编写一个程序,向用户询问有多少辆汽车。
    	随后,程序使用 new 来创建一个由相应数量的 car 结构组成的动态数组。
    	接下来,程序提示用户输入每辆车的生产商(可能由多个单词组成)和年份信息。
    	请注意,这需要特别小心,因为它将交替读取数值和字符串。
    	最后,程序将显示每个结构的内容。
    	该程序运行情况如下:
    
    	How many cars do you wish to catalog? 2
    	Car #1:
    	Please enter the make: Hudson Hornet
    	Please enter the year made: 1952
    	Car #2:
    	Please enter the make: Kaiser
    	Please enter the year made: 1951
    	Here is your collection:
    	1952 Hudson Hornet
    	1951 Kaiser
    */
    

    三、代码

    1.不符合要求的代码:

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main()
    {
    	//定义一个汽车的结构
    	struct car
    	{
    		string manufacturer;        //生产商
    		int year;        //年份
    	};
    
    	int num;         //汽车的数量
    	cout << "How many cars do you wish to catalog? ";
    	cin >> num;        //用户输入汽车的数量
    	car * information = new car[num];        //用 new 创建一个 car 结构的动态数组
    
    	//通过用户输入数量,动态创建表示汽车信息的数组
    	for (int i = 0; i < num; i++)
    	{
    		cout << "Car #" << i + 1 << ": \n";
    		cout << "Please enter the maker: ";
    		getline(cin, information[i].manufacturer);   //用户输入这辆汽车的生产商(不给用户输入生产商的机会)
    		cout << "Please enter the year made: ";
    		cin >> information[i].year;          //用户输入这辆汽车的年份
    	}
    
    	cout << "Here is your collection:\n";
    	//循环输出之前所输入的各汽车信息
    	for (int i = 0; i < num; i++)
    	{
    		cout << information[i].year << " ";        //年份
    		cout << information[i].manufacturer << "\n";       //生产商
    	}
    	delete[] information;         //释放 new 建立的内存
    
    	return 0;
    }
    

    问题:用户没有输入汽车生产商的机会,怎样才能输入?

    2.正确示例:

    #include<iostream>
    #include<string>
    
    using namespace std;
    
    //定义一个 car 结构
    struct car
    {
    	string manufacturer;        //生产商
    	int year;        //年份
    };
    
    int main()
    {
    	int num;         //汽车的数量
    	cout << "How many cars do you wish to catalog? ";
    	cin >> num;        //用户输入汽车的数量
    	cin.get();
    	car * information = new car[num];        //用 new 创建一个 car 结构的动态数组
    
    	//通过用户输入数量,动态创建表示汽车信息的数组
    	for (int i = 0; i < num; i++)
    	{
    		cout << "Car #" << i + 1 << ": \n";
    		cout << "Please enter the maker: ";
    		getline(cin, information[i].manufacturer);    //用户输入这辆汽车的生产商
    		cout << "Please enter the year made: ";
    		cin >> information[i].year;          //用户输入这辆汽车的年份
    		cin.get();
    	}
    
    	cout << "Here is your collection:\n";
    
    	//循环输出之前所输入的各汽车信息
    	for (int i = 0; i < num; i++)
    	{
    		cout << information[i].year << " ";        //年份
    		cout << information[i].manufacturer << "\n";       //生产商
    	}
    	delete[] information;         //释放 new 建立的内存
    
    	return 0;
    }
    

    解决办法:在 getline() 上一个 cin 输入之后添加 cin.get();

    四、总结:

    *****仅限于我目前学到的知识,之后加以补充

    1. cin
      ① cin>> 右面是一个字符时,从缓冲区读取一个非空白字符的字符后停止读取。
      ② cin>> 右面是一个字符串时,从缓冲区读取数据,若第一个字符为空白字符,则忽略并丢弃,读取下一个字符,直到遇到空白字符时停止读取,此空白符留在缓冲区

    2. cin.get()
      ① 无参数时,读入一个字符,包括换行符,常用来处理输入缓冲区中的换行符。
      ② 接受一个参数时,格式为 cin.get(char ch);,读入一个字符后结束读取。
      ③ 接受两个参数时,格式为 cin.get(array_name, ArSize);,从缓冲区读取数据,达到行尾或者读取了 ArSize - 1 个字符为止,且超过规定的字符数不会出现错误,会直接截断,cin.get() 不对此换行符进行处理,并将其留在缓冲区

    3. cin.getline()
      接受两个参数,格式为 cin.getline(array_name, ArSize);,函数从缓冲区读取数据,达到行尾或者读取了 ArSize - 1 个字符为止,且超过所规定的字符数会出现错误,cin.getline() 读取换行符后将其替换为空字符,并丢弃

    4. getline()
      声明在头文件<string>
      接受两个参数,格式为 getline(cin, string_name);,从缓冲区读取数据,遇到换行符时结束读取,且 getline() 读取此换行符后将其替换为空字符,并丢弃

    展开全文
  • cin.get(); //读取到数值装不下了,就自己加个\n结束 cin.getline(); //读取到\n,然后看数组能装多少就装多少

    cin.get()

    cin.get(String,ArSize);

    #include<iostream>
    int main()
    {
    using namespace std;
    const int ArSize = 5;
    char A[ArSize];
    char B[ArSize];
    
    cout << "Enter A:\n";
    cin.get(A,ArSize); 
    cout << "Enter B:\n";
    cin.get(B,ArSize);
    cout << A << "\n";
    cout <<  B << "\n";
    return 0;
    }
    

    输入A:
    abcdefg
    输出:
    Enter A:
    abcdefg
    Enter B:
    abcd
    efg


    输入A:
    abc
    输出:
    Enter A:
    abc
    Enter B:
    abc


    在输入A为abcdefg时,由于数组长度只有5,除去末尾需要填充\n,只能读取4个字符,于是 cin.get(A,ArSize); 取走了abcd,剩下的efg\n被cin.get(B,ArSize);读取,也因此,还没等我输入B的值,cin.get(B,ArSize);就已经取着efg\n跑了
    ————
    而在输入A为abc时,同样没等到输入B的值,就直接输出结果了,从输出结果可以看出B的值为\n,那这是因为我输入的是abc\n ,cin.get(A,ArSize);在取走abc后,把\n滞留下来了,导致cin.get(B,ArSize);读取到了\n,于是…cin.get(B,ArSize);啥也没带就直接跑了。

    cin.get(String,ArSize).get();

    .get()会读取掉一个字符,这就解决了上述cin.get(B,ArSize);啥也没带就直接跑的问题

    #include<iostream>
    int main()
    {
    using namespace std;
    const int ArSize = 5;
    char A[ArSize];
    char B[ArSize];
    
    cout << "Enter A:\n";
    cin.get(A,ArSize).get();
    cout << "Enter B:\n";
    cin.get(B,ArSize);
    cout << A << "\n";
    cout <<  B << ".\n";
    return 0;
    }
    

    输入A:
    abc
    输入B:
    efg
    Enter A:
    abc
    Enter B:
    efg
    abc
    efg


    输入A后,第一个cin.get(A,ArSize).get();读取,然后紧接着.get()会把\n读取掉。程序执行到cin.get(B,ArSize);我继续输入efg,程序得以按照预期正常执行!

    cin.getline()

    #include<iostream>
    int main()
    {
    using namespace std;
    const int ArSize = 5;
    char A[ArSize];
    char B[ArSize];
    
    cout << "Enter A:\n";
    cin.getline(A,ArSize);
    cout << "Enter B:\n";
    cin.getline(B,ArSize);
    cout << A << "\n";
    cout <<  B << "\n";
    return 0;
    }
    

    输入:
    abcdefg
    输出:
    Enter A:
    abcdefg
    Enter B:
    abcd


    输入A:
    abc
    输入B:
    efg
    Enter A:
    abc
    Enter B:
    efg
    abc
    efg


    可以看到在输入abcdefg时,相比cin.get(A,ArSize); efg没掉了

    简单点理解就是:
    cin.get(); //读取到数值装不下了,就自己加个\n结束
    cin.getline(); //读取到\n,然后看数组能装多少就装多少

    所以由于cin.getline(); 过于浪费,我们更多的是使用cin.get();


    当getline( )读取空行时,下一条输入语句将在前一条getline( )结束读取的位置开始读取;但当get( )(不是getline( ))读取空行后将设置失效位(failbit)。这意味着接下来的输入将被阻断,但可以用cin.clear()命令来恢复输入


    输入字符串比分配的空间长:如果输入行包含的字符数比指定的多,则getline( )和get( )将把余下的字符留在输入队列中,而getline( )还会设置失效位,并关闭后面的输入


    cin >> string_1;

    cin.getline(string_1,20)

    cin.get(string_1,20)

    cin.get(name,ArSize).get();<=>cin.get(name,ArSize);cin.get();

    (cin >> string_1).get(); <=> (cin >> string_1).get(ch);

    展开全文
  • cin,cin.get(),cin.getline()

    2021-05-14 14:43:02
    cin结束标识符的空白=空格、回车、制表符 系统通过回车识别用户完成信息键入 所谓从输入过程实际是系统从键盘输入缓冲队列中读取字符的过程,该过程在全部键入信息(回车结尾)后进行 cin:你的名字 #include<...
  • cin.getline() 接收一个字符串,可以接收空格并输出 cin.get() 接收一个字符串,结束符默认为回车键 getlin() 接收一个字符串,可以接收空格并输出,需包含“#include” 1、cin>> cin是将标准输入流...
  • 1.cin>> 1.1cin>>用法1:最基本,也是最常用的用法,输入一个数字: #include <iostream> using namespace std; main () { int a,b; cin>>a>>b; cout<<a+b<<endl; } ...
  • 总结一波cin的详细用法 正文 cin介绍 cin 是 C++ 的标准输入流对象,即 istream 类的对象。cin 主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout 是输出流对象,即 ostream 类的对象,...
  • cin.getline():C++读入一行字符串(整行数据) getline() 是 istream 类的成员函数,它有如下两个重载版本: istream & getline(char* buf, int bufSize); istream & getline(char* buf, int bufSize, char...
  • 文章目录cin用法cin.getline()用法getline()用法cin.get()的用法注意的问题 cin用法 用法:接收一个字符串,一个数字或一个字符,遇“空格”、“TAB”、“回车”就结束 #include <iostream> using namespace ...
  • cin.getline() 用法:接收一行字符串,可以接收空格并输出,可以控制接受的字符范围 #include <iostream> using namespace std; main () { char m[20]; cin.getline(m,5); cout<<m<<endl; } ...
  • 最近当做题时及被同学询问时,发现cincin.getline()、getline()与换行符之间总是存在相应的输入错误问题,所以今天弄清楚了,现分享之,望有助于各位同仁。 我们可以清楚的看到,当键盘上输入’A’时,被ch接受,...
  • 3. cin.get()用法1: a = cin.get()或cin.get(a)用法2:cin.get(arrayname,size)用法3:cin.get(arrayname,size,s) 本文转载自 https://blog.csdn.net/livecoldsun/article/details/25489429 1. 简单介绍输入缓冲区...
  • 文章目录cincin.get( )cin.getline() cin 特点:忽略空格,回车符,Tab等不可见的符号;当且仅当回车后数据才会传入; 用法: //输入一个数 int k; cin >> k; // 输入,直到不满足条件 while(cin >> ...
  • 在他们混合使用时有时会出现无法输入字符串或者字符串多出空格的情况 ...如果cin或者scanf留下的是空格,那么下面使用getline,getchar,cin.getline输入的字符串前面会多一个空格 如果cin或者scanf留
  • C++中使用cin输入string类型的变量时,会出现遇到空格就认为输入完成的情况,这里就需要用到另外一种输入方式getline #include<iostream> #include<string> using namespace std; int main() { string ...
  • 一、cin 输入一个字符或者一个数字。 #include<iostream> using namespace std; int main() ...二、getline() 用于接受字符串,并可以接受空格并输出。 #include<iostream> #includ...
  • 1.cin.get() 用法1: cin.get(字符变量名)可以用来接收字符 #include <iostream> using namespace std; int main() { char ch; ch = cin.get(); cout << ch << endl; return 0; } 输入:...
  • 在C++中,有很多的输入方法,各有不同,今天给大家分享一篇关于cincin.get()、cin.getline()、getline()、gets、getchar()、peek()的文章。 输入原理简述 程序的输入都建有一个缓冲区,即输入缓冲区。每次输入过程...
  • cin的读取字符规则: cin遇到回车、空格、tab键 结束,但是缓冲区还存在这三个字符,并没有将这三个字符丢弃,且指针光标在这三个字符之前,也就是说,下一次通过其他输入函数读取时,是可以读到这三个字符的。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 74,521
精华内容 29,808
关键字:

cin.getline