basic_istream :: seekg (), кажется, не работает - PullRequest
0 голосов
/ 22 мая 2018

Следующая программа должна вывести что-то вроде:

Begin found
space found
End found

, но это не так.

#include <sstream>
#include <istream>
#include <string>
#include <cctype>
#include <iostream>

bool Match(std::istream& stream, const std::string& str)
{
    std::istream::pos_type cursorPos = stream.tellg();

    std::string readStr(str.size(),'\0');

    stream.read(&readStr[0],str.size());
    stream.seekg(cursorPos);
    if(std::size_t(stream.gcount()) < str.size() || readStr != str)
        return false;

    return true;
}

bool Take(std::istream& stream, const std::string& str)
{
    if(!Match(stream,str))
        return false;

    for(std::string::size_type i = 0; i < str.size(); ++i)
        stream.get();

    return true;
}

int main()
{
    std::string testFile = "BEGIN END";

    std::stringstream ss(testFile);
    auto c = ss.peek();
    while(!ss.eof() && ss.tellg() != -1)
    {
        if(Take(ss,"BEGIN"))
            std::cout << "Begin found" << std::endl;
        else if(Take(ss,"END"))
            std::cout << "End found" << std::endl;
        else if(std::isspace(c))
        {
            ss.get();
            std::cout << "space found" << std::endl;
        }
        else
            std::cout << "Something else found" << std::endl;
    }

    return 0;
}

Что я заметил, это то, что она выдает

Begin found
Something else found

Когда я перехожу к отладчику, кажется, что когда я до пробела, он сначала проверяет, есть ли от Match() до "BEGIN", он получает позицию курсора через tellg(), который имеетзначение 5.Но затем, когда он неожиданно завершается с ошибкой, а затем проверяет Match() с "END", курсор находится на -1, то есть в конце.

Таким образом, кажется, что вызов seekg() не работаетили я не правильно его использую.

1 Ответ

0 голосов
/ 22 мая 2018

Когда ваша программа входит в основной цикл, она сначала выполняет take с входным потоком и "BEGIN" в качестве аргументов.Match возвращает true, а get вызывается 5 раз, так как это длина BEGIN.

Затем он снова проходит цикл.Он снова вызывает матч.В этот момент pos находится на 5, длина начинается.Он пытается прочитать символы len (BEGIN), но в вашем потоке строки не так много символов, поэтому он покидает цикл в позиции -1 и устанавливает флаг ошибки.

Поскольку поток является состоянием ошибкиследующий вызов seekg не имеет ожидаемого эффекта, объясняющего поведение вашей программы.

...