你真的了解getline()的返回值吗?—— basic_istream::getline() 与 string::getline

我们会经常用到getline()函数,去从流中读取指定的一行内容。尤其是在牛客或者leetcode上刷题的同学,应该更为熟悉这个用法。但是通过这篇文章,你可能会发现你根本没有那么了解getline()这个函数。

问题起因:
今天在写项目的时候用到了C++ifstream流,利用它来读取指定文件的内容。我的读取文本如下:
在这里插入图片描述
我的预期是这样的:利用getline()一行一行的读文件,以空行作为界限,每一个小段做一个处理。

vector<string>v;
for(int i=0;i<2;++i){	
			
			v.clear();
			
			while( getline(in,str) ){         //读到空行的时候就跳出循环                              
				
				//一行一行读
				v.push_back(str);

			}//end of while

			//把下一行的空行读走;铺垫下一个host列表   咦,好像这里不用再操作了,空行已经被读走...
			Print(v);

简单的实现,感觉代码没有任何问题。不过就是这简单的操作却让人伤神了半天。 注意我的for循环是循环两次,按照预期,当读入空行时,getline()返回0,判断为假跳出循环,那么应该是会读入文本的前两段然后Print()打印。但是结果却是:文本内容全部打印! 我真的是懵逼,在风中凌乱。。。这么简单的几行代码也会出错,我哭/(ㄒoㄒ)/~~

上网百度getline()的用法,发现好像也没有错误呀:

函数声明:
ssize_t getline(char **lineptr, size_t *n, FILE *stream);

返回值
成功:返回读取的字节数。
失败:返回-1。

读到空行返回值不是为0吗,但是为什么却没有按照预期跳出循环呢,我再哭/(ㄒoㄒ)/~~

最后,当我看到了 basic_istream::getline()这个概念,才猛然醒悟 —— 我们一般用的getline()是C++库里处理string流的getline(),而在项目中用到的文件ifstream读取的getline()是处理isream流的getline()。 这两个getline()原来是有区别的。 来看一下C++reference标准里边的后者返回值的定义:
在这里插入图片描述额emm…,看不懂英文没关系,我来总结:在后者也就是处理istream流额时候,getline()的返回值是这样的:
只要可以读到文件内容(包括空行),返回值就一直是True. 如果读取失败,那么会抛出相对应的异常。

所以在我上述项目中的情境下,while()判断其实一直是true,因为一直都有读到内容,所以外层for循环其实是没有限制力的/(ㄒoㄒ)/~~ 所以如果要达到之前的预期,需要在循环体内手动的进行空行的判断:

for(int i=0;i<2;++i){	
			
			v.clear();
			
			while( getline(in,str) ){         //读到空行的时候就跳出循环                              
			   
				if(str.size()==0)
				   break;
				
				//一行一行读
				v.push_back(str);

			}//end of while

ok,这个故事告诉我们做学问还是不能一知半解,努力吧少年(ง •_•)ง

  • 28
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拥抱@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值