How to test whether stringstream operator>> has parsed a bad type and skip it

前端 未结 5 2110
误落风尘
误落风尘 2020-11-21 06:49

I am interested in discussing methods for using stringstream to parse a line with multiple types. I would begin by looking at the following line:



        
5条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-21 07:27

    You can use std::istringstream::eof() to validate input like this:

    #include 
    #include 
    #include 
    
    // remove white-space from each end of a std::string
    inline std::string& trim(std::string& s, const char* t = " \t")
    {
        s.erase(s.find_last_not_of(t) + 1);
        s.erase(0, s.find_first_not_of(t));
        return s;
    }
    
    // serial input
    std::istringstream in1(R"~(
     2.34 3 3.f 3.d .75 0 wibble 
    )~");
    
    // line input
    std::istringstream in2(R"~(
    2.34
     3
    
    3.f
    3.d
    .75
    0
    wibble 
    )~");
    
    int main()
    {
        std::string input;
    
        // NOTE: This technique will not work if input is empty
        // or contains only white-space characters. Therefore
        // it is safe to use after a conditional extraction
        // operation >> but it is not reliable after std::getline()
        // without further checks.
    
        while(in1 >> input)
        {
            // input will not be empty and will not contain white-space.
            double d;
            if((std::istringstream(input) >> d >> std::ws).eof())
            {
                // d is a valid double
                std::cout << "d1: " << d << '\n';
            }
        }
    
        std::cout << '\n';
    
        while(std::getline(in2, input))
        {
            // eliminate blank lines and lines
            // containing only white-space (trim())
            if(trim(input).empty())
                continue;
    
            // NOW this is safe to use
    
            double d;
            if((std::istringstream(input) >> d >> std::ws).eof())
            {
                // d is a valid double
                std::cout << "d2: " << d << '\n';
            }
        }
    }
    

    This works because the eof() check ensures that only the double was entered and not garbage like 12d4.

提交回复
热议问题