在 C++ 中使用 istringstream 将字符串拆分为整数

问题描述 投票:0回答:3

我正在尝试使用

istringstream
将一个简单的字符串拆分为一系列整数:

#include <string>
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

int main(){

    string s = "1 2 3"; 
    istringstream iss(s);   

    while (iss)
    {
        int n;
        iss >> n;
        cout << "* " << n << endl;
    } 
}

我得到:

* 1
* 2
* 3
* 3

为什么最后一个元素总是出现两次?怎么解决?

c++ stl istringstream
3个回答
35
投票

它出现了两次,因为你的循环是错误的,正如(间接)在http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5

while (iss)
不是与本场景中的
while (iss.eof())
不同)。

具体来说,在第三次循环迭代中,

iss >> n
成功并获取您的
3
,并使流保持良好状态。然后,由于这个良好的状态,循环第四次运行,直到下一个(第四次)
iss >> n
随后失败,循环条件才被打破。但在第四次迭代结束之前,您仍然第四次输出
n
...。

尝试:

#include <string>
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

int main()
{
    string s = "1 2 3"; 
    istringstream iss(s);   
    int n;

    while (iss >> n) {
        cout << "* " << n << endl;
    } 
}

1
投票

希望这有帮助:
国际空间站:1 2 3
迭代 1
iss:1 2 3(初始)
n=1
国际空间站:2 3
//* 打印 1
迭代 2:
iss:2 3(初始)
n=2
国际空间站:3
//* 打印 2
迭代 3
国际空间站:3
n=3
伊丝:''
迭代 4
伊丝:''
n 未更改//为 iss 的 eof 设置标志,因为没有来自流的进一步输入
伊丝 : ''

正如上面的帖子所正确提到的, while (iss) 与 while (iss.eof()) 没有什么不同。
在内部,函数(istream::operator>>) 通过首先构造一个 sentry 对象来访问输入序列(noskipws 设置为 false[这意味着空格是分隔符,您的列表将为 1,2,3])。然后(如果 good[此处 eof 未达到]),它调用 num_get::get [获取下一个整数] 来执行提取和解析操作,相应地调整流的内部状态标志。最后,它在返回之前销毁哨兵对象。

参考:http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/


0
投票

常见的情况是分割成一个向量,完全避免混乱的

while
循环和EOF陷阱(参见这个答案,它很好地阐述了为什么OP的代码不起作用):

#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

int main() {
    std::string s = "1 2 3"; 
    std::istringstream istr(s);
    const std::vector<int> values{std::istream_iterator<int>(istr),
                                  std::istream_iterator<int>()};

    for (const int n : values) {
        std::cout << n << "\n";
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.