A pit on c++ istringstream

c++primer exercise 8.11
: The program in this section defines the isringstream object in the outer while loop. If the record object is defined outside the loop, what changes do you need to make to the program? Re-program, move the definition of record outside the while loop, and verify that the modification method you envision is correct?
(Probably means to read argv[] to get the file, use getline to read each line from it, and then use isringstream to extract each word)

(The program I started below)

vector<string>v;
    string temp;
    for(auto p=argv+1;p!=argv+argc;++p){
    
    
        ifstream input(*p);
        if(input){
    
    
            while(getline(input,temp)/*input>>temp*/){
    
    
                // v.push_back(temp);
               istringstream recod(temp);
                string s;
                // cout<<temp<<endl;
                while(recod>>s){
    
    
                    // cout<<s<<endl;
                    v.push_back(s);
                }
            }
        }else
            cerr<<" could not open:"+string(*p);
    }
    for (auto &str : v)
    {
    
    
        cout<<str<<endl;
    }

The following figure is the modified program.
According to the title, recod is mentioned outside, but why is the answer wrong???
All lines should be read, but only a few words in one line were read! ! !

	vector<string>v;
    string temp;
    istringstream recod;
    for(auto p=argv+1;p!=argv+argc;++p){
    
    
        ifstream input(*p);
        if(input){
    
    
            while(getline(input,temp)/*input>>temp*/){
    
    
                // v.push_back(temp);
                recod.str(temp);
                string s;
                // cout<<temp<<endl;
                while(recod>>s){
    
    
                    // cout<<s<<endl;
                    v.push_back(s);
                }
            }
        }else
            cerr<<" could not open:"+string(*p);
    }
    for (auto &str : v)
    {
    
    
        cout<<str<<endl;
    }
    

wrong reason: An isringstream stream will set eofbit and failbit at the end of reading. At this time, we will fail to read in using the isringstream stream.
Solution: call the clear() member function of the isringstream stream, reset and restore!

The following is one more line

	vector<string>v;
    string temp;
    istringstream recod;
    for(auto p=argv+1;p!=argv+argc;++p){
    
    
        ifstream input(*p);
        if(input){
    
    
            while(getline(input,temp)/*input>>temp*/){
    
    
                // v.push_back(temp);
               	recod.clear();
                recod.str(temp);
                string s;
                // cout<<temp<<endl;
                while(recod>>s){
    
    
                    // cout<<s<<endl;
                    v.push_back(s);
                }
            }
        }else
            cerr<<" could not open:"+string(*p);
    }
    for (auto &str : v)
    {
    
    
        cout<<str<<endl;
    }

Conclusion: C++ has many pits

Guess you like

Origin blog.csdn.net/adlatereturn/article/details/105055646