0

I have this problem and need really fast solving. It's my code:

    void stypendium() {
        string tresc = "";
        string temp;
        stringstream ss;
        fstream file;
        vector<float> grades;
        float grade, sum, av;
        file.open(this->plik, ios_base::in);
        if(!file.is_open()) {
            ofstream fileTmp(this->plik);
            fileTmp.close();
            file.open(this->plik, ios_base::in);
        }
        while (file >> temp) {
            if(strspn( temp.c_str(), "-.0123456789" ) == temp.size()) {
                ss.str("");
                ss << temp;
                ss >> grade;
                grades.push_back(grade);
            }
        };
        sum = 0;
        for(int i=0;i<grades.size();++i) {
            sum += grades[i];
        }
        av = sum / grades.size();
        cout << sum << "/" << grades.size() << "=" << av;
        file.close();
    }

};

Problem is that in line

ss << temp;


nothing gets to the stream, though the temp has value;

2 Answers2

1

Use the ss.clear() member function to properly prepare the stringstream for the first and successive grade values. Here is the reference: std::basic_ios::clear. Keep in mind that clear() can throw an exception.


Based on the most recent source code edit, the while loop body is nearly the same as before.

 while (file >> temp) {
     if(strspn( temp.c_str(), "-.0123456789" ) == temp.size()) {
         ss.str("");
         //
         // Call the clear() member function here
         //
         ss.clear(); 
         ss << temp;
         ss >> grade;
         grades.push_back(grade);
     }
 };

A simple test file having grade values on a line by line basis, has each line is obtained a single time, as well as the last input file grade value being added to the grades vector only once.

  • Without the `ss.str()`, the `ss << temp;` appends to the internal buffer. So if the previous string actually had multiple tokens, this will keep extracting from where it was up to. Also, if the previous string's final token didn't have trailing whitespace, then it will be concatenated with `temp` which is probably a mistake. This may or may not be what OP wants. – M.M Apr 08 '14 at 10:55
  • Since the layout of the input file is not known, I have added back the `ss.str("")` for the rest of us. – CPlusPlus OOA and D Apr 08 '14 at 10:56
0

You also need to call ss.clear(); after doing ss.str("");.

The reason is that when the stringstream is extracting a float, if it reaches the end of the string before it has definitely finished reading a float then it will set the eof state on the stream. Then, since eof is set, future conversions fail. You have to clear() to reset the eof state.

M.M
  • 138,810
  • 21
  • 208
  • 365