从终端读取一行数据,fgets,gets,c++ string类定义的getline

浏览: 164 发布日期: 2016-11-27 分类: c++

从终端读取一行数据,且看fgets,gets的区别,结果说话。

先看fgets.例子如下:

       char str[100];
       while(fgets(str,100,stdin)!=NULL){
	     cout<<"***"<<str<<"---"<<endl;
       }
</pre><pre class="cpp" name="code">/*输入,第二行是一个空行
abcde

abc
*/

结果:


可以看到,fgets会把包括换行符在内的字符都输入到str中,同时也是以换行符作为结束标记的


再看gets

    char str[100];
    while(gets(str)!=NULL){
	   cout<<"***"<<str<<"---"<<endl;
	}
/*输入,第二行是一个空行
abcde

abc
*/

结果:


可以看到,gets同样以换行符作为结束标记,不同的是,其并不把换行符读取进str中


再看看c++里string类的getline函数
	int x;
	std::string sline;
	std::cin>>x;
	getline(std::cin,sline);
	std::cout<<"*****"<<sline<<"----"<<std::endl;

输入1:4和回车键
结果:
可以看到,程序并未给我们任何输入一行字符串的机会就直接退出了。

输入2:   3abc和回车键
结果:
可以看到,getline函数读取了到了字符abc。

从这两个输入可以推测出,getline是以换行符作为结束标记的(当然可能还有其他版本也许可以更改结束标记),第一个输入:4和回车键,则输入缓冲区有两个字符即4和回车符,cin先从输入缓冲区中把整数4载入x,此时输入缓冲区还剩下回车符,getline读取到缓冲区的回车符直接就结束掉了。所以,输入1的结果和输入2的结果就很显然了。那么如何解决这个问题呢,我们当然希望,可以输入完整数、按完回车之后、再输入字符串的啊。其实知道原理后就明白了,我们只需要把输入缓冲区先强制清空然后在调用getline,代码如下:
	int x;
	std::string sline;
	std::cin>>x;
	std::cin.sync();//强制情况缓冲区
	getline(std::cin,sline);
	std::cout<<"*****"<<sline<<"----"<<std::endl;
输入:3
           abc abc
结果:



除了用cin.sync()之外,还可以使用cin.ignore(),以忽略字符,我们往往只需要忽略输入中的少数字符,因此多数情况是使用ignore的


返回顶部