使用istringstream向vector插入值时最后一个元素重复的原因是什么?
问题原因解释
第一段代码重复插入最后一个元素的根因
while(iss) 判断的是当前输入流是否处于有效状态(无错误标记),你的代码执行逻辑是这样的:
- 流初始有效,进入循环,读取到1,插入vector,流仍有效
- 再次判断流有效,进入循环,读取到2,插入vector,流仍有效
- 再次判断流有效,进入循环,读取到3,插入vector,流仍有效(此时刚读完3,还没尝试读取下一个内容,不会触发eof标记)
- 再次判断流有效,进入循环,执行
iss>>temp时已经没有内容可读,读取操作失败,流会同时设置eofbit和failbit变为无效状态,但此时temp没有被新值覆盖,保留了上一次读取的3 - 你还是把这个未更新的3插入了vector,下一次判断
while(iss)时流已经无效,才退出循环
所以最终vector里多了一个重复的3。
关于第二段代码“正常运行”的补充说明
你写的第二段do-while代码其实也存在隐患,它只是在你输入1 2 3的场景下刚好没出问题:
- do-while会先执行一次读取操作,再判断是否到文件尾
- 当你输入的内容刚好是整数结尾时,读完最后一个整数后判断
!iss.eof()为假,刚好退出,不会重复插入 - 但如果输入为空、或者输入末尾有非整数内容时,这段代码会把读取失败的垃圾值插入到vector中,本质也是错误写法。
推荐的正确写法
直接把读取操作放到while的判断条件里即可,这样会先执行读取、再判断读取是否成功,只有读取有效才会进入循环插入值:
#include <iostream> #include <string> #include <sstream> #include <vector> using namespace std; int main (){ string s; getline(cin ,s); vector<int> vec; istringstream iss{s}; int temp; while(iss >> temp) { vec.push_back(temp); } for (auto val:vec){ cout << val << " "; } return 0; }
内容的提问来源于stack exchange,提问作者user16521673
相关产品推荐
相关产品推荐

