【问题标题】:unexpected exit of loop with ifstream getline使用 ifstream getline 意外退出循环
【发布时间】:2017-04-05 15:33:20
【问题描述】:

请看下面的代码:

std::string s;
while(std::getline(m_File,s))
{
    std::cout<<"running\n";
    std::string upper(s);
    std::transform(upper.begin(),upper.end(),upper.begin(),toupper);


    if(upper.find("*NODE") != std::string::npos)
    {
        std::cout<<"start reading nodes\n";
        readnodes();

    }
    std::cout<<"\n open? "<<m_File.is_open()<<"\n";

}

我正在尝试从以下输入文件中提取数据。(INPUT FILE)

 *NODE
 1 ,1.0,2.0
 2, 2.6,3.4
 3, 3.4, 5.6
 *NODE
 4, 4, 5
 5, 5, 6

但是当我运行它时,程序找到了 *NODE 的第一个实例并调用 readnode() 函数,但是 无法识别 *NODE 的第二个实例。 m_File 是同一类的 ifstream 对象,其中 readnode() 被定义为私有函数。

readnode():

 void mesh::readnodes()
 {
 char c;                                              
 int id;
 float x,y;

   while(m_File>>id>>c>>x>>c>>y)
   {
    node temp(id,x,y);
    m_nodes.push_back(temp);

    // dummy string for reading rest of line. 
    std::string dummy;
    std::getline(m_File,dummy);

   }
}

【问题讨论】:

  • 您的 while 循环不会在第二个节点处停止。您需要先读取每一行,然后与 NODE 进行比较,然后将其解析为数字序列。

标签: c++ file-io while-loop ifstream getline


【解决方案1】:

为什么会意外退出?

while(m_File>>id>>c>>x>>c>>y)
{
    node temp(id,x,y);
    m_nodes.push_back(temp);

    // dummy string for reading rest of line. 
    std::string dummy;
    std::getline(m_File,dummy);
}

在上面的代码中,m_File&gt;&gt;id&gt;&gt;c&gt;&gt;x&gt;&gt;c&gt;&gt;y曾经读取id,x,y,但是在读取了前几行节点后,当m_File&gt;&gt;id&gt;&gt;c&gt;&gt;x&gt;&gt;c&gt;&gt;y失败时它会中断,这也可能会改变m_File的状态。结果getline(m_File, s)返回false,导致意外退出。

解决办法:

我没有遇到基于您的原始程序的解决方案。但既然你想从字符串中提取值,那么 boost 可能是一个更好的解决方案,检查:

while (getline(m_File, s))
{
    if (boost::to_upper_copy(s) == "*NODE") continue;

    std::vector<std::string> SubStr;
    boost::algorithm::split(SubStr, s, boost::is_any_of(" ,"));

    SubStr.erase(std::remove(SubStr.begin(), SubStr.end(), ""), SubStr.end());
    m_nodes.push_back(node(atoi(SubStr[0].c_str()), atof(SubStr[1].c_str()), atof(SubStr[2].c_str())));
}

获取结果:

for (auto Itr : m_nodes)
    std::cout << Itr.id << "," << Itr.x << "," << Itr.y << std::endl;

输出

1,1.0,2.0
2,2.6,3.4
3,3.4,5.6
4,4,5
5,5,6

【讨论】:

  • 你发现了错误,它纠正了我的问题。
  • 我很高兴它有帮助。
【解决方案2】:

感谢您在 readnode() 函数中找出 while 循环条件中的错误。 更好的解决方案是如下更改 readnode() 函数。

void mesh::readnodes()
{
char c;                         //temp.variable for recieving ','.
int id;
float x,y;
std::string temp;

// changes made in the while loop condition
while(m_File.peek() != '*' and m_File.peek() != EOF )
{
    //getline(m_File,temp);
    m_File>>id>>c>>x>>c>>y;
    node temp(id,x,y);
    m_nodes.push_back(temp);

    // dummy string for reading rest of line.
    std::string dummy;
    std::getline(m_File,dummy);

}
}

【讨论】:

    猜你喜欢
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 2019-08-18
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多