【问题标题】:std::getline is not doing what I expect it to do See my code belowstd::getline 没有做我期望它做的事情请参阅下面的代码
【发布时间】:2020-09-15 16:59:21
【问题描述】:

我正在使用 RHEL5.4、QT4.8 只有文件的第一行在 getline 中得到处理。 我在 stringstream ss 上的 qDebug 打印文件中的所有行。 我在记录结构上的 qDebug 重复文件第一行中的数据以获得总数 文件中的行数。 我在结果向量上的 qDebug 再次重复文件第一行中的数据以获得总数 文件中的行数。

首先我在头文件中声明一个记录结构。

    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();


   }

【问题讨论】:

  • 你的文件里有什么,你期望什么,你得到什么?
  • @EPurdy edit 你的问题是要添加该信息,不要放在 cmets 中。
  • 谁将其作为副本关闭,此问题与格式化提取后getline 失败无关,因为此代码中没有格式化提取,getline 是唯一正在执行的提取.我重新打开了这个问题。

标签: c++ ifstream getline


【解决方案1】:

您在每次循环迭代中重用tss,但您并未在每次迭代中清除其错误状态,仅清除其字符串内容。当第一次迭代完成时,如果该行没有被',' 字符终止,则流可能已达到 EOF 并且现在处于错误状态。使用空白字符串调用tss.str() 不会清除错误状态,您需要为此调用tss.clear(),否则下一次调用getline(tss) 将失败。

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!
}

否则,根本不要重复使用stringstream,在每次迭代时创建一个新的:

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);
}

也就是说,当while 循环完成时,您的后续for 循环假定result 包含46 个元素,但while 循环中没有任何东西可以保证这一点。 for 循环应该查看 result.size()

for(size_t x = 0; x < result.size(); x++)

【讨论】:

  • tss.clear() 成功了。我也在实现 result.size() 边界。非常感谢您的快速回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 2020-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多