【问题标题】:How to save and restore an std::istringstream's buffer?如何保存和恢复 std::istringstream 的缓冲区?
【发布时间】:2014-12-01 01:45:01
【问题描述】:

我正在使用istringstream 逐字阅读string。但是,当我的条件失败时,我需要能够将istringstream 恢复到读取前一个单词之前。我的示例代码有效,但我想知道是否有更直接的方法来使用流来完成此操作。

std::string str("my string");
std::istringstream iss(str);

std::ostringstream ossBackup << iss.rdbuf(); // Writes contents of buffer and in the process changes the buffer
std::string strBackup(ossBackup.str());      // Buffer has been saved as string

iss.str(strBackup);                          // Use string to restore iss's buffer
iss.clear();                                 // Clear error states
iss >> word;                                 // Now that I have a backup read the 1st word ("my" was read)

// Revert the `istringstream` to before the previous word was read.
iss.str(strBackup);                         // Restore iss to before last word was read
iss.clear();                                // Clear error states
iss >> word;                                // "my" was read again

【问题讨论】:

  • 嗯,这似乎取决于您如何准确定义“当我的条件失败时”。您可以只检查 operator&gt;&gt;() 操作留下的值,并将流状态设置为失败。这是用于这种方法的example

标签: c++ istringstream


【解决方案1】:

如果您愿意,可以使用tellg()seekg() 来保存和恢复您的位置:

#include <string>
#include <sstream>

int main()
{
    std::istringstream iss("some text");

    std::string word;

    // save the position
    std::streampos pos = iss.tellg();

    // read a word
    if(iss >> word)
        std::cout << word << '\n';

    iss.clear(); // clear eof or other errors
    iss.seekg(pos); // move to saved position

    while(iss >> word)
        std::cout << word << '\n';

}

【讨论】:

  • 嗯,现在你这么说我觉得很明显,因为我无法想出一个有效的解决方案而感到愚蠢。
【解决方案2】:

这确实只保证对字符串流有效,但您可以反复调用unget(),直到达到空格字符:

#include <iostream>
#include <sstream>

template <int n>
std::istream& back(std::istream& is)
{
    bool state = is.good();

    auto& f = std::use_facet<std::ctype<char>>(is.getloc());
    for (int i = 0; i < n && is; ++i)
        while (is.unget() && !f.is(f.space, is.peek()));

    if (state && !is)
        is.clear();
    return is;
}

int main()
{
    std::stringstream iss("hello world");
    std::string str;

    std::cout << "Value Before: ";
    iss >> str;

    std::cout << str << std::endl;
    iss >> back<1>; // go back one word

    std::cout << "Value after: ";
    iss >> str;

    std::cout << str;
}

Live Demo

【讨论】:

    猜你喜欢
    • 2010-11-29
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    相关资源
    最近更新 更多