文件末尾的空格导致 C++ 中 EOF 检查失败

发布于 2024-08-08 20:30:50 字数 505 浏览 9 评论 0原文

我正在从具有三列的文件中读取数据。例如,数据看起来像:

3  START  RED
4  END    RED

要读入数据,我使用以下检查:

while (iFile.peek() != EOF) {
   // read in column 1
   // read in column 2
   // read in column 3
}

我的问题是循环通常会执行额外的循环。我很确定这是因为很多文本编辑器似乎在实际内容的最后一行之后放置了一个空行。

我做了一些谷歌搜索并搜索了SO,发现了一些类似的情况,例如 从文本文件读取直到 EOF 重复最后一行 但是我似乎无法完全适应给出的解决方案来解决我的问题。有什么建议吗?

I am reading in data from a file that has three columns. For example the data will look something like:

3  START  RED
4  END    RED

To read in the data I am using the following check:

while (iFile.peek() != EOF) {
   // read in column 1
   // read in column 2
   // read in column 3
}

My problem is that the loop usually does an extra loop. I am pretty sure this is because a lot of text editors seem to put a blank line after the last line of actual content.

I did a little bit of Googling and searched on SO and found some similar situations such as Reading from text file until EOF repeats last line however I couldn't quite seem to adapt the solution given to solve my problem. Any suggestions?

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

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

发布评论

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

评论(5

烏雲後面有陽光 2024-08-15 20:30:51

EOF 不是预测而是错误状态。因此,您不能像现在一样使用它来预测您是否可以读取第 1、2 和 3 列。因此,C++ 中的常见模式是:

while (input >> obj1 >> obj2) {
  use(obj1, obj2);
}

All operator>>(istream& ; is, T&) 返回输入流,并且当在布尔上下文中使用时,只要最后一次提取成功,流就为“true”。然后就可以安全地使用提取的对象了。

EOF is not a prediction but an error state. Hence, you can't use it like you're using it now, to predict whether you can read Column 1, 2 and 3. For that reason, a common pattern in C++ is:

while (input >> obj1 >> obj2) {
  use(obj1, obj2);
}

All operator>>(istream& is, T&) return the inputstream, and when used in boolean context the stream is "true" as long as the last extraction succeeded. It's then safe to use the extracted objects.

⒈起吃苦の倖褔 2024-08-15 20:30:51

假设 iFile 是一个 istream

您应该在任何任何错误时跳出循环,而不仅仅是在 EOF 时(可以使用 < code>iFile.eof(),顺便说一句),因为当任何格式失败将流设置为除 EOF 之外的错误状态时,这是一个无限循环。通常需要在循环中间、读取所有内容(无论成功与否)之后以及输入之前打破读取循环。

为了确保不再有任何有趣的事情发生,您可以在循环之后重置流状态,然后尝试仅读取空白,直到到达 EOF:

while( !iFile.eof() )
{
   iFile >> std::ws;
   string line;
   std::getline(iFile,line);
   if(!line.empty()) error(...);
}

Presuming iFile is an istream:

You should break out of the loop on any error, not only on EOF (which can be checked for with iFile.eof(), BTW), because this is an endless loop when any format failure sets the stream into a bad state other that EOF. It is usually necessary to break out of a reading loop in the middle of the loop, after everything was read (either successfully or not), and before it is entered.

To make sure there isn't anything interesting coming anymore, you could, after the loop, reset the stream state and then try to read whitespace only until your reach EOF:

while( !iFile.eof() )
{
   iFile >> std::ws;
   string line;
   std::getline(iFile,line);
   if(!line.empty()) error(...);
}
浅紫色的梦幻 2024-08-15 20:30:51

如果任何读取失败(读取列数据的地方),只需跳出 while 循环即可。大概您现在位于文件末尾并读取最后一个“不正确”行

If any of the reads fail (where you read the column data), just break out of the while loop. Presumably you are then at the end of the file and reading the last 'not correct' line

无敌元气妹 2024-08-15 20:30:51

也许您会认为处理空格和其他无效输入是个好主意。也许对第 1、2、3 列进行一些基本验证也是可取的。

Maybe you'll consider it a good idea to handle whitespace and other invalid input then. Perhaps some basic validation of columns 1,2,3 would be desirable as well.

死开点丶别碍眼 2024-08-15 20:30:51

不必担心循环次数:只需验证数据并处理无效输入即可。

基本上,检查您是否有三列要阅读,如果您不确定是因为文件已结束还是因为其他问题。

Don't worry about the number of times that you loop: just validate your data and handle invalid inputs.

Basically, check that you have three columns to read and if you don't decide if it's because the file is over or because of some other issue.

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