2010-06-17 45 views
34

大部分像C语言++写入文件时,就把即使我们错过写这样的语句EOF字符:我们可以自己写一个EOF角色吗?

filestream.close

但是有什么办法,我们可以把EOF字符根据我们的要求,以C++为例。或者除了使用C++提供的功能外,我们还可以使用其他任何方法。

如果您需要了解更多的信息,请随时发表评论。

在此先感谢。

编辑:感谢您的支持,但这里是一个除了这个问题:

如果我们想欺骗OS和放置一个EOF字符的文件和EOF了一些数据后写什么,这样应用程序像notepad.exe无法在我们的EOF字符后读取。 我已阅读与此主题相关的问题的答案,并且已经知道,现在的操作系统通常不会看到EOF字符,而是检查文件的长度以获得有关文件长度的正确理念,但是,在操作系统中必须有一个过程来检查文件的长度,然后更新文件记录。

对不起,如果我在我的估计任何一点错了,但请帮助我因为它可以导致很多新的想法。

+1

我一定很傻,因为我不知道这意味着什么。 – 2010-06-17 11:15:44

+14

你的意思是像'CP/M'(control-Z)中的EOF字符?我不认为过去30年的任何操作系统都使用EOF字符作为文件结束标记? – 2010-06-17 11:16:11

+1

加EOF指标是操作系统特定的,例如在UNIX上,它的ctrl-D – 2010-06-17 11:39:52

回答

48

没有EOF字符。 EOF的定义“不等于任何有效的字符代码”。通常它是-1。它在任何时候都不会写入文件。

DOS中有一个历史的EOF字符值(CTRL + Z),但它现在已经过时了。

要回答Apoorv的后续问题:操作系统从不使用文件数据来确定文件长度(文件不以任何方式“空终止”)。所以你不能欺骗操作系统。也许旧的,愚蠢的程序不会在CTRL + Z字符后读取。我不会认为任何Windows应用程序(甚至是记事本)都会这样做。我的猜测是用一个空字符(\0)欺骗他们会更容易。

+0

这是一个阅读EOF - 我们正在谈论写作。 – 2010-06-17 11:23:04

+8

我只解释了EOF实际是什么,它不是一个字符代码。我没有看到你的问题与答案。 – ypnos 2010-06-17 16:20:25

+0

所以我想欺骗一个自定义的流编写器类,我已经人为接受EOF。除了完成我的覆盖测试之外,没有任何有用的目的。 – Stephen 2014-02-27 17:09:53

3

如果通过EOF字符表示Control-Z之类的东西,那么现代操作系统不需要这样的事情,而C++运行时不会为你写一个。你当然可以自己写一个:

filestream.put(26);  // write Ctrl-Z 

但是没有很好的理由这样做。也没有必要做:

filesystem.close(); 

的文件流会为你自动关闭时,它的析构函数被调用,但它是(我觉得)很好的做法这样做。

7

实际上在C++中,没有使用fprintf()或ostream机制写入文件的物理EOF字符。 EOF是一个I/O条件,指示没有更多数据要读取。

一些像CP/M这样的早期磁盘操作系统实际上使用物理0x1A(ASCII SUB字符)来表示EOF,因为文件系统只是以块的形式维护文件大小,因此您永远不知道文件的字节长度。随着在目录中存储实际长度计数的出现,将“EOF”字符存储为“带内”文件数据的一部分不再是典型的。

2

在现代文件系统EOF不是一个字符,所以在完成写入文件时不必发出它。您只需关闭该文件或让操作系统在您的进程终止时为您执行此操作。

+0

我有疑问:如果EOF仅用于返回值目的&没有这样的字符实际写入文件,那么C程序如何确定End of文件已到达&没有更多的输入可用(文件读取进程)?请帮助我。 – 2012-11-13 06:34:06

+1

@SandeepSingh - 文件系统上文件的大小决定是否没有更多输入可用。如果EOF是一个字符,那么零字节文件如何存在? – mouviciel 2012-11-13 06:39:41

+0

感谢您的澄清。 – 2012-11-14 03:55:13

10

我来到这里的时候通过Kernighan &里奇C演习。

Ctrl键 + d发送从stdio.hEOF常数相匹配的字符。

(编辑:这是在Mac OS X;感谢@markmnl用于指出在Windows 10相当于是按Ctrl +ž

+0

谢谢,这是我需要的。 – 2015-04-17 18:42:27

+0

Ctrl-Z为我做了(Windows 10) – markmnl 2015-09-29 13:37:51

4

有作为 “EOF” 字符没有这样的事。关闭流自身的事实是“EOF”条件。

当按下Ctrl键+d在UNIX壳,简单地关闭标准输入流,而这又是由shell识别为“EOF”,它退出。

因此,要“发送”一个“EOF”,只需关闭需要发送“EOF”的流。

1

没有人提到过系统调用[f]truncate,这就是如何缩短文件而不重新创建文件。

truncate()ftruncate()功能引起的path命名或fd引用被截断的大小精确length字节的常规文件。

如果以前的文件大于此大小,则额外的数据将丢失。如果以前的文件较短,则扩展,扩展部分读取为空字节('\0')。

了解这是将任何类型的数据写入文件的独特操作。该文件是一个线性的字节数组,以某种方式在磁盘上进行布置,元数据表明它有多长; truncate更改元数据。

3

在Windows下,如果在stdin中遇到ASCII 26(EOF),它将停止读取其余数据。我相信写这个字符也会终止输出发送到stdout,但我还没有证实这一点。您可以将流切换到二进制模式as in this SO question

#include <io.h> 
#include <fcntl.h> 
... 
_setmode(0, _O_BINARY) 

而且你不仅会停止的0x0A被转换为0X0D的0x0A,但你也将获得读/写0X1A以及能力。请注意,您可能必须同时切换stdin(0)和stdout(1)。

+0

感谢提及stdin,stdout。尽管如此,它仍然不起作用。用C++编译是否有所作为? – eleijonmarck 2014-12-15 15:30:52

+0

否语言不会有所作为,因为这是Windows API的问题。我可以确认上面的代码,但请确保将0更改为要切换的流的编号。 – Malvineous 2014-12-16 02:07:19

+0

噢,我看到了,所以我必须切换到'_setmode(0,_0_BINARY)'而不是'_setmode(stdin,_0_BINARY)'将stdin设置为二进制 – eleijonmarck 2014-12-16 05:57:24

相关问题