peek()前方多处?

dom*_*ica 6 c++ peek

假设我有一个外部while循环来读取每个字符并将其输出到控制台.我还想标记一个单词,如果找到它,并使用peek方法我可以找到一个单词的第一个实例.有没有办法窥探前方的多个地方.例如,如果我找"payday"这个词.我知道我可以将它输入到字符串中并搜索字符串,但我想以二进制模式读取文件,我不想从外部循环中删除任何值.如果我有一个带有read方法的内部循环,则不会通过外部循环显示这些值.

谢谢

int main()

ifstream strm;
char *chr = new char;

strm.open("mytext.txt",ios::out | ios::binary);

while (strm.read(chr,1)
{
    if (strm.peek() == 'p';
  {
    cout << "found a word beginning with 'p'" << endl;
  //what if I want to read multiple characters ahead.  Peek will read only one.
  }

}
Run Code Online (Sandbox Code Playgroud)

Lie*_*yan 6

您可以使用seekg方法在istream中跳转.

如果以二进制模式打开文件,可以使用tellg方法标记要跳转到的位置.

但是,如果在文本模式下打开文件,最好使用offset(即strm.seekg(offset,strm.cur))进行跳转,因为在文本模式下,tellg和seekg会对newline等多字节字符进行计数.因此,如果您检测到下一个字符将是"p",那么您可以读取下一个n字符,然后跳回-n字符,如果它不是您要查找的字符.


Mat*_* M. 5

有多种方法可以实现这一点,但传统方法只是在原始文件和"用户"函数之间再添加一层:词法分析器.

例如,具有无限缓冲的Lexer:

class Lexer {
public:
    Lexer(std::istream& s): source(s) { this->read(); }

    explicit operator bool() const {
        return not queue.empty();
    }

    Lexer& operator>>(std::string& s) {
        assert(*this and "Test for readiness before calling this method");

        s = queue.front();
        queue.pop_front();

        if (queue.empty()) { this->read(); }
        return *this;
    }

    std::string const* peek(size_t const i) {
        while (source and queue.size() < i) { this->read(); }
        return queue.size() >= i ? &queue[i] : nullptr;
    }

private:
    void read() {
        queue.emplace_back();
        if (not (source >> queue.back())) { queue.pop_back(); }
    }

    std::istream& source;
    std::deque<std::string> queue;
}; // class Lexer
Run Code Online (Sandbox Code Playgroud)

注意:很明显,你可以完全限制词法分析器的缓冲,或者使其缓冲除了单词之外的其他内容......自定义类的主要优点是你可以指定语义!