读取文本文件时使用 getline

发布于 2024-09-16 20:21:57 字数 626 浏览 3 评论 0原文

我最初构建一个类似索引的机制,使用 getline 读取文本文件的每一行,检查它是否与已知的标头声明 (string.compare) 匹配,并将tellg 位置保存为该点的索引。 然后我的意图是使用eekg(index,ios::beg)来查找文件中标题所在的位置。 在构建索引并调用 seeg(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 的使用是否不正确?

I'm initially building an index-like mechanism, read each line of the textfile using getline, checking if it matches a known header declaration (string.compare) and saving the tellg position as an index to that point.
My intention is then to use seekg(index,ios::beg) to seek to the place in the file where the header is.
After reading through the file once when building my index and calling seekg(0,ios::beg) the next getline returns an empty string where I expect to see the first line in the file.

a portion of my code is below to better highlight my issue

//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)

the getLineID function returns an int depending on the result of the string comparison.

is the use of getline incorrect if I need to re-read the file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黯然#的苍凉 2024-09-23 20:21:57

您的问题是由于您在流中设置了错误位而引起的。
流上的操作将被忽略,直到 Bad 位被重置。

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

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

,但这不是您的主要问题:

您正在使用经典反模式来读取文件:
还不如用这个。

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() 返回作为第一个参数传递的流。因此,流在布尔上下文中使用。当流在布尔上下文中使用时,它会转换为可用作布尔值的类型;如果没有错误,则该对象的值相当于 true,否则相当于 false。

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

Your problem is caused because you have a Bad bit set inside the stream.
Operations on the stream will be ignored until the Bad bit has been reset.

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

Note: A Bad bit is one of many error conditions including EOF

But that is not your major problems:

You are using the Classic anti pattern for reading a file:
Rather use this.

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

The problem is that the EOF is not set until you read past it.
The last valid read reads UPTO but not past the EOF (therefore EOF is not set).

So consider the situation where you have read the last line in the file. The EOF has not been set as you have not read past it. So the loop is entered. You now execute getline(). This tries to read past EOF as there is absolutely no data to read (not a single byte). So getline() fails now you are calling getlineID() using lineRead whose value is indeterminate (the standard does not say what happens to lineRead when EOF condition is hit; but it probably has the value of last line read as you don't seem to reset it inside the loop).

Another problem with this code is it only checks for EOF. What happens when another type of error occurs? The loop actually gets stuck in an infinite loop; this is because when an error flag is set no more reading happens so you can never reach to the EOF.

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

The solution is to perform the read operation in the while loop test. This works because getline() returns the stream passed as the first parameter. Therefore the stream gets used in a boolean context. When a stream is used in a boolean context it is converted into a type that can be used as a boolean; the value of this object is equivalent true if there are no errors and false otherwise.

In this situation the read is attempted, but if it fails the loop is never entered.

梦巷 2024-09-23 20:21:57

在此处发布并搜索各个网站后,我

m_fileIn.clear();

通过清除错误标志(我假设 eof 错误)在该行之前

getline (m_fileIn,lineRead);

添加了该行,我能够正常继续。

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

After posting here and trawling various websites I added the line

m_fileIn.clear();

before the line

getline (m_fileIn,lineRead);

by clearing the error flags (i'm assuming eof error) I was able to continue as normal.

Martin - I'd be really interested to find out more on the anti-pattern which I unknowingly used, I've updated my code to include your changes, many thanks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文