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

发布于 2024-10-20 02:33:22 字数 472 浏览 4 评论 0原文

我正在尝试使用 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

为什么最后一个元素总是出现两次?如何修复它?

I'm trying to use istringstream to split a simple string into a series of integers:

#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;
    } 
}

And i get:

* 1
* 2
* 3
* 3

Why is the last element always coming out twice? How to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

撩发小公举 2024-10-27 02:33:22

它出现两次,因为你的循环是错误的,如 http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5while (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;
    } 
}

It's coming out twice because your looping is wrong, as explained (indirectly) at http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.5 (while (iss) is not dissimilar from while (iss.eof()) in this scenario).

Specifically, on the third loop iteration, iss >> n succeeds and gets your 3, and leaves the stream in a good state. The loop then runs a fourth time due to this good state, and it's not until the next (fourth) iss >> n subsequently fails that the loop condition is broken. But before that fourth iteration ends, you still output n... a fourth time.

Try:

#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;
    } 
}
枕花眠 2024-10-27 02:33:22

希望这有帮助:
国际空间站: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 notchange//为 iss 的 eof 设置标志,因为没有来自流的进一步输入
iss : ''

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

请参阅:http://www.cplusplus.com/reference/istream/ istream/运算符%3E%3E/

Hope this helps:
iss : 1 2 3
Iteration 1
iss : 1 2 3 (Initially)
n=1
iss : 2 3
//* 1 is printed
Iteration 2:
iss : 2 3 (Initially)
n=2
iss : 3
//* 2 is printed
Iteration 3
iss : 3
n=3
iss : ''
Iteration 4
iss : ''
n not changed//Flag set for eof of iss as no further input from stream
iss : ''

And as rightly mentioned by the above post while (iss) is not dissimilar from while (iss.eof()).
Internally, the function(istream::operator>>) accesses the input sequence by first constructing a sentry object (with noskipws set to false[This means that space is separator and your list will be 1,2,3]). Then (if good[here eof not reached]), it calls num_get::get [Get the next integer] to perform both the extraction and the parsing operations, adjusting the stream's internal state flags accordingly. Finally, it destroys the sentry object before returning.

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

以可爱出名 2024-10-27 02:33:22

常见情况是直接使用迭代器拆分为向量,从而完全避免混乱的 while 循环和 EOF 陷阱(请参阅 这个答案很好地阐述了为什么OP的代码不起作用):

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

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

    for (const int n : values) {
        std::cout << n << "\n";
    }
}

The common case is to split into a vector directly using an iterator, avoiding the messy while loop and EOF gotchas entirely (see this answer which elaborates nicely on why OP's code doesn't work):

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

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

    for (const int n : values) {
        std::cout << n << "\n";
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文