3

を使って一語ずつ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
4

2 に答える 2

1

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

于 2014-10-06T18:38:19.067 に答える