代码之家  ›  专栏  ›  技术社区  ›  NeomerArcana

basic_istream::seekg()似乎不起作用

  •  0
  • NeomerArcana  · 技术社区  · 8 年前

    以下程序应输出如下内容:

    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 . 但当它预期失败,然后检查 匹配() 具有 "END" ,光标位于 -1 也就是说,结束。

    所以看起来 seekg() 呼叫不起作用,或者我没有正确使用。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Spacemoose    8 年前

    当程序进入主循环时,它首先用输入流执行take,并将begin作为参数。match返回true,get的调用次数是begin的5倍。

    然后它再次通过循环。它再次调用match。此时,位置为5,即开始的长度。它试图读取len(begin)字符,但您的stringstream没有那么多字符,因此它将循环留在位置-1,并设置一个错误标志。

    因为流是一个错误状态,下面的seekg调用没有预期的效果,解释了程序的行为。

    推荐文章