0

I am using RHEL5.4, QT4.8 Only the first line of the file gets handled in the getline. My qDebug on the stringstream ss prints all the lines in the file. my qDebug on the records struct repeats the data in the first line of the file for the total number of lines in the file. My qDebug on the result vector again repeats the data in the first line of the file for the total number of lines in the file.

First I declare a record structure in the header file.

    struct data_rec
    {
        std::string name;
        std::string value;
    };
    std::ifstream myfile("foo.bar");
    if(!myfile.is_open()){
       qDebug() << "Could not open file";
   }else {
       qDebug() << "File opened";
       std::string line;

       std::stringstream ss;
       std::stringstream tss;

       while(std::getline(myfile,line))
       {
           data_rec records;
           tss.str("");
           ss<<line<<std::endl;
           tss<<line<<std::endl;   //; temp stringstream

           std::getline(tss, records.name, ',');
           std::getline(tss, records.value, ',');

           qDebug()<<"!!!" << records.name.c_str();
           qDebug()<<"!!!" << records.value.c_str();

           result.push_back(records);

           tss.str(std::string());
       }

       for(int x = 0; x < 46; x++)
       {
          QString tstr1 = QString::fromStdString(result[i].name);
          QString tstr2 = QString::fromStdString(result[i].value);
           qDebug() << tstr1 << " -> " << tstr2;
       }

       qDebug() << QString::fromStdString(ss.str());

       qDebug() <<  "\n////////////////////////////////////////\n";
       myfile.close();


   }
E Purdy
  • 131
  • 1
  • 8
  • 2
    What is in your file, what do you expect, what do you get? – S.M. Sep 15 '20 at 17:01
  • @EPurdy [edit] your question to add that info, don't put it in comments. – Remy Lebeau Sep 15 '20 at 17:21
  • Whoever closed this as a duplicate, this issue has nothing to do with `getline` failing after a formatted extraction, since there is no formatted extraction in this code, `getline` is the only extraction being performed. I have reopened the question. – Remy Lebeau Sep 15 '20 at 17:30

1 Answers1

3

You are reusing tss on each loop iteration, but you are not clearing its error state on each iteration, only its string content. When the first iteration is finished, the stream has likely reached EOF and is now in an error state, if the line is not terminated by a ',' character. Calling tss.str() with a blank string will not clear the error state, you need to call tss.clear() for that, or else the next call to getline(tss) will fail.

while (std::getline(myfile, line))
{
    data_rec records;
    // tss.str(""); // <-- redundant here!

    ss << line << std::endl;
    tss << line << std::endl;

    std::getline(tss, records.name, ',');
    std::getline(tss, records.value, ',');

    qDebug() << "!!!" << records.name.c_str();
    qDebug() << "!!!" << records.value.c_str();

    result.push_back(records);

    tss.str(std::string());
    tss.clear(); // <-- add this!
}

Otherwise, simply don't reuse a stringstream at all, create a new one on each iteration:

while (std::getline(myfile, line))
{
    data_rec records;

    std::istringstream tss(line); // <-- here!
    ss << line << std::endl;

    std::getline(tss, records.name, ',');
    std::getline(tss, records.value, ',');

    qDebug() << "!!!" << records.name.c_str();
    qDebug() << "!!!" << records.value.c_str();

    result.push_back(records);
}

That said, when the while loop is finished, your subsequent for loop assumes the result contains 46 elements, but there is nothing in the while loop which guarantees that. The for loop should be looking at result.size() instead:

for(size_t x = 0; x < result.size(); x++)
Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
  • The tss.clear() did the trick. I'm also implementing the result.size() boundary. Thanks so much for your quick answer. – E Purdy Sep 15 '20 at 17:25