读取文件函数如何识别C ++中文本文件的结尾?

时间:2014-08-02 05:17:04

标签: c++ memory-management text-files

据您所知,在C ++中读取文本文件有两种标准(在这种情况下每行有2个数字):

两种标准方法是:

假设每一行由2个数字组成,并通过令牌读取令牌:

#include <fstream>
std::ifstream infile("thefile.txt");    
int a, b;
while (infile >> a >> b)
{
    // process pair (a,b)
}

基于行的解析,使用字符串流:

#include <sstream>
#include <string>
#include <fstream>
std::ifstream infile("thefile.txt");

std::string line;
while (std::getline(infile, line))
{
    std::istringstream iss(line);
    int a, b;
    if (!(iss >> a >> b)) { break; } // error

    // process pair (a,b)
}

我还可以使用以下代码查看文件是否结束:

while (!infile.eof())

我的问题是:

  

问题1:这个函数如何理解一行是最后一行   线?我的意思是&#34; eof()如何返回false \ true?&#34;

     

据我所知,他们读了一部分记忆。是什么   属于文件的部分与部件之间的差异   不是吗?

     

问题2:无论如何都要欺骗这个功能?!我的意思是,是吗?   可以在文本文件的中间添加一些东西(例如   通过Hex编辑器工具)并使eof()错误地返回True   文本文件的中间?

感谢您的时间和考虑。

1 个答案:

答案 0 :(得分:2)

  

问题1:这个函数如何理解一行是最后一行?我的意思是&#34; eof()如何返回false \ true?&#34;

它没有。这些函数知道您何时尝试读取文件中的最后一个字符。他们不一定知道一条线是否是最后一条线。 &#34;文件&#34;不是你能用溪流阅读的唯一东西。键盘输入,专用设备,互联网套接字:所有都可以使用正确的I / O流读取。当从标准输入读取时,流不知道我输入的下一个东西是否是control-Z。

对于计算机磁盘上的文件,大多数现代操作系统存储与文件分开的文件元数据。这些元数据包括文件的长度(通常是文件上次修改时和上次读取时)。在这些系统上,流缓冲区不是I / O流的基础,它知道文件中的当前读取位置并知道文件的长度。当读取位置达到文件长度时,流缓冲器发出EOF信号。

但是,这并不普遍。有一些不那么常见的操作系统不能使用存储在别处的元数据概念。磁盘文件上的文件结尾在这些系统上与在键盘上用户输入的文件末尾一样令人惊讶。

  

据我所知,他们读了一部分记忆。属于该文件的部分与不属于该部分的部分之间有什么区别?

了解内存和磁盘文件之间的区别。这两者之间存在巨大差异。除非您使用嵌入式计算机,否则内存比磁盘空间更受限制。

  问题2:无论如何都要欺骗这个功能?!我的意思是,是否可以在文本文件的中间添加一些内容(例如通过Hex编辑器工具)并使eof()错误地在文本文件的中间返回True?

这在很大程度上取决于操作系统如何实现文件。在大多数现代操作系统中,答案不仅仅是&#34; no&#34;但是&#34;不!&#34;。使用一些特殊签名来指示磁盘文件中文件结尾的概念是许多计算机科学概念中的一个,这些概念在很大程度上已被倾倒到一堆非常聪明的#34;想法。你在互联网上问了你的问题。这很可能意味着您使用的是Windows机器,Linux机器或Mac。所有这些都将文件的长度存储为与文件内容分开的元数据。

但是,需要能够清除文件结束指示符。一个程序可能正在写入文件,而另一个程序正在从中读取文件。当作者仍处于活动状态时,读者可能会点击EOF。读者需要清除EOF指示器以继续阅读作者所写的内容。 C ++ I / O流提供了实现这一目标的能力。每个I / O流都具有clear功能。它是否有效,这是一个不同的故事。清除将暂时起作用,但下一次读取可能会重置EOF位。例如,当我在键盘上键入control-Z时,这意味着我已完成与程序的交互,期间,我的下一步行动可能是出去吃午饭。