提取运算符(>>)是否可以覆盖变量?

时间:2012-10-16 15:50:26

标签: c++ stringstream

我写了以下测试代码:

int main(int argc, char* argv[]) {
    stringstream ss;
    int num;

    ss << "54321";
    ss >> num;
    ss.str("");
    ss << "12345";
    ss >> num;

    fprintf(stderr, "%d\n", num);
}

令我惊讶的是,结果是54321.如何使用提取运算符(&gt;&gt;)正确覆盖变量?

2 个答案:

答案 0 :(得分:8)

第一次提取后,您到达了流的末尾,因此eofbit已设置,第二次提取失败。

int main(int argc, char* argv[]) {
    stringstream ss;
    int num;

    ss << "54321";
    ss >> num;

    // eofbit was set above,
    // we need to clear it
    ss.clear();

    ss.str("");
    ss << "12345";
    ss >> num;

    fprintf(stderr, "%d\n", num);
}

在尝试第二次提取之前调用clear()成员函数。 第二个问题是内部get指针的位置,它不会自动重置。使用seekg()进行设置。

编辑:被攻击的东西不是必要的,here解释。

答案 1 :(得分:4)

当流到达流的末尾时,std::ios_base::eofbit被设置。在尝试提取任何日期之前,提取检查是否设置了任何状态标志,如果是,则它不会执行任何操作并且提取失败:

std::stringstream ss;
ss << "54321";
ss >> num; // sets eof:
std::cout << "eof: " << ss.eof() << "\n";

要在设置任何状态标志后让流执行任何操作,您需要先清除标志:

ss.clear();
ss << "12345";
if (ss >> num) {
    std::cout << "num=" << num << "\n";
}
else {
    std::cout << "failed to extract a value\n";
}

就个人而言,我通常不使用输出运算符来设置字符串流的内容。相反,我通常使用str()成员:

std::ostringstream out; // note: this is just an output string stream
...
out.clear();            // the clear is still needed
out.str("12345");