首页 文章

从文本文件中读取时使用getline

提问于
浏览
1

我最初构建一个类似索引的机制,使用getline读取文本文件的每一行,检查它是否与已知的头部声明(string.compare)匹配,并将tellg位置保存为该点的索引 . 我的意图是使用seekg(index,ios :: beg)来寻找 Headers 所在文件中的位置 . 在构建索引并调用seekg(0,ios :: beg)之后读取文件一次后,下一个getline返回一个空字符串,我希望看到文件中的第一行 .

我的代码的一部分在下面,以更好地突出我的问题

//build the index
while (! m_fileIn.eof())
{
   getline (m_fileIn,lineRead);
   int lineID = getLineID(lineRead);
   if(lineID==1)       //if its an STRM 
   {
   //save the index
   }
}

// start reading the file data
m_fileIn.seekg(0,ios::beg);
//read first line (title)

getLineID函数返回一个int,具体取决于字符串比较的结果 .

如果我需要重新读取文件,是否使用getline不正确?

2 回答

  • 1

    在这里发布并拖网各种网站后,我添加了该行

    m_fileIn.clear();
    

    在线之前

    getline (m_fileIn,lineRead);
    

    通过清除错误标志(我假设eof错误)我能够正常继续 .

    马丁 - 我真的很想知道更多关于我在不知不觉中使用的反模式,我已经更新了我的代码以包含你的更改,非常感谢 .

  • 2

    您的问题是由于您在流中设置了错误位而导致的 .
    在重置坏位之前,将忽略对流的操作 .

    // After the loop reset the Bad Bits.
    m_fileIn.clear()
    

    注意:坏位是许多错误条件之一,包括EOF

    但这不是你的主要问题:

    您正在使用 Classic anti pattern 来读取文件:
    而是使用它 .

    while (getline (m_fileIn,lineRead))
    {
       int lineID = getLineID(lineRead);
       if(lineID==1)       //if its an STRM 
       {
       //save the index
       }
    }
    

    问题是EOF在您阅读之前未设置 .
    最后一次有效读取读取UPTO但未超过EOF(因此未设置EOF) .

    因此,请考虑您已阅读文件中最后一行的情况 . EOF尚未设置,因为您没有读过它 . 所以循环进入 . 您现在执行getline() . 这会尝试读取过去的EOF,因为绝对没有要读取的数据(不是单个字节) . 所以getline()现在失败,你现在使用lineRead调用getlineID(),其值是不确定的(标准没有说明当EOF条件被击中时lineRead会发生什么;但它可能有最后一行读取的值,因为你似乎没有在循环内重置它) .

    此代码的另一个问题是它只检查EOF . 发生其他类型的错误会发生什么?循环实际上陷入无限循环;这是因为当设置错误标志时不再发生读取,因此您永远无法达到EOF .

    while (! m_fileIn.eof())
    {
       getline (m_fileIn,lineRead)
       int lineID = getLineID(lineRead);
       if(lineID==1)       //if its an STRM 
       {
       //save the index
       }
    }
    

    解决方案是在while循环测试中执行读取操作 . 这是有效的,因为getline()返回作为第一个参数传递的流 . 因此,流在布尔上下文中使用 . 当在布尔上下文中使用流时,它将转换为可用作布尔值的类型;如果没有错误,则此对象的值等效,否则为false .

    在这种情况下,尝试读取,但如果失败,则永远不会进入循环 .

相关问题