C++ 我们可以自己写一个EOF字符吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3061135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can we write an EOF character ourselves?
提问by Apoorv Saxena
Most of the languages like C++ when writing into a file, put an EOF character even if we miss to write statements like :
大多数像 C++ 这样的语言在写入文件时,即使我们没有编写如下语句,也会放置一个 EOF 字符:
filestream.close
文件流.close
However is there any way, we can put the EOF character according to our requirement, in C++, for an instance. Or any other method we may use apart from using the functions provided in C++.
但是有没有办法,我们可以根据我们的要求放置EOF字符,例如在C++中。或者除了使用 C++ 中提供的函数之外我们可以使用的任何其他方法。
If you need to ask more of information then kindly do give a comment.
如果您需要询问更多信息,请发表评论。
Thanks in advance.
提前致谢。
EDIT: Thanks for your support but here's an addition to this question:
编辑:感谢您的支持,但这里是这个问题的补充:
What if, we want to trick the OS and place an EOF character in a file and write some data after the EOF so that an application like notepad.exe is not able to read after our EOF character. I have read answers to the question related to this topic and have come to know that nowdays OS generally don't see for an EOF character rather check the length of file to get the correct idea of knowing about the length of the file but, there must be a procedure in OS which would be checking the length of file and then updating the file records.
如果我们想欺骗操作系统并在文件中放置一个 EOF 字符并在 EOF 之后写入一些数据,那么像 notepad.exe 这样的应用程序就无法读取我们的 EOF 字符后该怎么办。我已经阅读了与该主题相关的问题的答案,并且已经知道现在的操作系统通常看不到 EOF 字符,而是检查文件的长度以正确了解文件的长度,但是,有必须是操作系统中的一个过程,它会检查文件的长度,然后更新文件记录。
I am sorry if I am wrong at any point in my estimation but please do help me coz it can lead to a lot of new ideas.
如果我的估计有任何错误,我很抱歉,但请帮助我,因为它可以带来很多新想法。
回答by ypnos
There is no EOF character. EOF by definition "is unequal to any valid character code". Often it is -1. It is not written into the file at any point.
没有 EOF 字符。根据定义,EOF“不等于任何有效的字符代码”。通常是-1。它不会在任何时候写入文件。
There is a historical EOF character value (CTRL+Z) in DOS, but it is obsolete these days.
在 DOS 中有一个历史的 EOF 字符值 (CTRL+Z),但现在已经过时了。
To answer the follow-up question of Apoorv:The OS never uses the file data to determine file length (files are not 'null terminated' in any way). So you cannot trick the OS. Perhaps old, stupid programs won't read after CTRL+Z character. I wouldn't assume that any Windows application (even Notepad) would do that. My guess is that it would be easier to trick them with a null (\0
) character.
回答 Apoorv 的后续问题:操作系统从不使用文件数据来确定文件长度(文件不会以任何方式“空终止”)。所以你不能欺骗操作系统。也许旧的、愚蠢的程序在 CTRL+Z 字符后不会读取。我不认为任何 Windows 应用程序(甚至记事本)都会这样做。我的猜测是用空 ( \0
) 字符来欺骗他们会更容易。
回答by chbrown
I came here while going through the Kernighan & Ritchie Cexercises.
我是在进行 Kernighan & Ritchie C练习时来到这里的。
Ctrl+Dsends the character that matches the EOF
constant from stdio.h
.
Ctrl+D发送与 中的EOF
常量匹配的字符stdio.h
。
(Edit: this is on Mac OS X; thanks to @markmnl for pointing out that the Windows 10 equivalent is Ctrl+Z)
(编辑:这是在 Mac OS X 上;感谢@markmnl 指出 Windows 10 等效为Ctrl+ Z)
回答by B.Gen.Hyman.O.Neill
Well, EOF
is just a value returned by the function defined in the C stdio.h
header file. Its actually returned to all the reading functions by the OS, so its system dependent. When OS reaches the end of file, it sends it to the function, which in its return value than places most commonly (-1
), but not always. So, to summarize, EOF
is not character, but constant returned by the OS.
EDIT: Well, you need to know more about filesystem, look at this.
嗯,EOF
只是Cstdio.h
头文件中定义的函数返回的值。它实际上由操作系统返回到所有读取功能,因此它依赖于系统。当操作系统到达文件末尾时,它会将其发送给函数,该函数的返回值比最常见的地方 ( -1
),但并非总是如此。所以,总而言之,EOF
不是字符,而是操作系统返回的常量。编辑:嗯,你需要了解更多关于文件系统的信息,看看这个。
Hi, to your second question:
你好,你的第二个问题:
once again, you should look better into filesystems
. FAT is very nice example, becouse you can find many articles about it, and its principles are very similiar to NTFS. Anyway, once again, EOF is NOT a character
. You cannot place it in file directly. If you could do so, imagine the consequences, even "dumb" image file could not be read by the system.
再一次,你应该更好地了解filesystems
. FAT 是一个很好的例子,因为你可以找到很多关于它的文章,它的原理与 NTFS 非常相似。无论如何,再一次,EOF 是NOT a character
. 您不能将其直接放在文件中。如果你能这样做,想象一下后果,即使是“哑”图像文件也无法被系统读取。
Why? Becouse OS works like very complex structure of layers. One of the layer is the filesystem driver. It makes sure that it transfers data from every filesystem known to the driver. It provides bridge between applications and the actuall system of storing files into HDD.
为什么?因为操作系统就像非常复杂的层结构。其中一层是文件系统驱动程序。它确保它从驱动程序已知的每个文件系统传输数据。它在应用程序和将文件存储到 HDD 的实际系统之间提供了桥梁。
To be exact, FAT filesystem uses so-called FAT table - it is a table located close to the start of the HDD (or partition) adress space, and it contains map of all clusters (little storage cells). OK, so now, when you want to save some file to the HDD, OS (filesystem driver) looks into FAT table, and searches for the value "0x0". This "0x0" value says to the OS that cluster which adress is described by the location of that value in FAT table is free to write.
确切地说,FAT 文件系统使用所谓的 FAT 表——它是一个靠近 HDD(或分区)地址空间起始位置的表,它包含所有簇(小存储单元)的映射。好的,现在,当您想将某个文件保存到 HDD 时,OS(文件系统驱动程序)会查看 FAT 表,并搜索值“0x0”。这个“0x0”值告诉操作系统,由该值在 FAT 表中的位置描述的集群可以自由写入。
So it writes into it the first part of the file. Than, it looks for another "0x0" value in FAT, and if found, it writes second part of the file into cluster which it points to. Than, it changes the value of the first FAT table record where the file is located to the physical adress of the next in our case second part of the file.
所以它将文件的第一部分写入其中。然后,它在 FAT 中寻找另一个“0x0”值,如果找到,它将文件的第二部分写入它指向的簇。然后,它将文件所在的第一个 FAT 表记录的值更改为下一个文件的第二部分的物理地址。
When your file is all stored on HDD, now there comes the final part, it writes desired EOF value, but into FAT table, not into the "data part" of the HDD. So when the file is read next time, it knows this is the end, don′t look any further.
当您的文件全部存储在 HDD 上时,现在是最后一部分,它将所需的 EOF 值写入 FAT 表,而不是写入 HDD 的“数据部分”。所以下次读取文件时,它知道这是结束了,不要再看下去了。
So, now you see, if you would want to manually write EOF value into the place it doesen′t belong to, you have to write your own driver which would be able to rewrite the FAT record, but this is practically impossible to do for begginers.
所以,现在你看到了,如果你想手动将 EOF 值写入它不属于的地方,你必须编写自己的驱动程序来重写 FAT 记录,但这实际上是不可能的初学者。
回答by Amardeep AC9MF
Actually in C++ there is no physical EOF character written to a file using either the fprintf() or ostream mechanisms. EOF is an I/O condition to indicate no more data to read.
实际上,在 C++ 中,没有使用 fprintf() 或 ostream 机制将物理 EOF 字符写入文件。EOF 是一种 I/O 条件,表示没有更多的数据要读取。
Some early disk operating systems like CP/M actually did use a physical 0x1A (ASCII SUB character) to indicate EOF because the file system only maintained file size in blocks so you never knew exactly how long a file was in bytes. With the advent of storing actual length counts in the directory it is no longer typical to store an "EOF" character as part of the 'in-band' file data.
一些早期的磁盘操作系统如 CP/M 实际上确实使用物理 0x1A(ASCII SUB 字符)来指示 EOF,因为文件系统仅以块为单位维护文件大小,因此您永远不知道文件的确切长度(以字节为单位)。随着在目录中存储实际长度计数的出现,将“EOF”字符存储为“带内”文件数据的一部分不再是典型的做法。
回答by Malvineous
Under Windows, if you encounter an ASCII 26 (EOF) in stdin, it will stop reading the rest of the data. I believe writing this character will also terminate output sent to stdout, but I haven't confirmed this. You can switch the stream to binary mode as in this SO question:
在 Windows 下,如果在 stdin 中遇到 ASCII 26 (EOF),它将停止读取其余数据。我相信写这个字符也会终止发送到 stdout 的输出,但我还没有证实这一点。您可以将流切换到二进制模式,如此 SO 问题所示:
#include <io.h>
#include <fcntl.h>
...
_setmode(0, _O_BINARY)
And not only will you stop 0x0A being converted to 0x0D 0x0A, but you'll also gain the ability to read/write 0x1A as well. Note you may have to switch both stdin (0) and stdout (1).
您不仅可以停止将 0x0A 转换为 0x0D 0x0A,而且还可以获得读/写 0x1A 的能力。请注意,您可能必须同时切换 stdin (0) 和 stdout (1)。
回答by Malvineous
If by the EOF character you mean something like Control-Z, then modern operating systems don't need such a thing, and the C++ runtime will not write one for you. You can of course write one yourself:
如果 EOF 字符的意思是 Control-Z 之类的东西,那么现代操作系统不需要这样的东西,而且 C++ 运行时不会为您编写一个。你当然可以自己写一个:
filestream.put( 26 ); // write Ctrl-Z
but there is no good reason to do so. There is also no need to do:
但没有充分的理由这样做。也没有必要做:
filesystem.close();
as the file stream will be closed for you automatically when its destructor is called, but it is (I think) good practice to do so.
因为在调用其析构函数时文件流将自动为您关闭,但(我认为)这样做是一种很好的做法。
回答by rustyx
There is no such thing as the "EOF" character. The fact of closing the stream in itself is the "EOF" condition.
没有“EOF”字符这样的东西。关闭流本身的事实是“EOF”条件。
When you press Ctrl+Din a unix shell, that simply closes the standard input stream, which in turn is recognized by the shell as "EOF" and it exits.
当您在 unix shell 中按Ctrl+D时,这只会关闭标准输入流,而标准输入流又被 shell 识别为“EOF”并退出。
So, to "send" an "EOF", just close the stream to which the "EOF" needs to be sent.
因此,要“发送”一个“EOF”,只需关闭需要发送“EOF”的流。
回答by zwol
Nobody has yet mentioned the [f]truncate
system calls, which are how you make a file shorter without recreating it from scratch.
还没[f]truncate
有人提到系统调用,它是你如何在不从头开始重新创建文件的情况下缩短文件的方法。
The
truncate()
andftruncate()
functions cause the regular file named bypath
or referenced byfd
to be truncated to a size of preciselylength
bytes.If the file previously was larger than this size, the extra data is lost. If the file previously was shorter, it is extended, and the extended part reads as null bytes (
'\0'
).
该
truncate()
和ftruncate()
功能造成名为常规文件path
或引用fd
的恰恰是被截断的大小length
字节。如果以前的文件大于此大小,则额外的数据将丢失。如果之前的文件较短,则会对其进行扩展,并且扩展部分读取为空字节 (
'\0'
)。
Understand that this is a distinct operation from writing any sort of data to the file. The file is a linear array of bytes, laid out on disk somehow, with metadata that says how long it is; truncate
changes the metadata.
理解这与将任何类型的数据写入文件是不同的操作。该文件是一个字节的线性数组,以某种方式布置在磁盘上,元数据表明它有多长;truncate
更改元数据。
回答by mouviciel
On modern filesystems EOF is not a character, so you don't have to issue it when finishing to write to a file. You just have to close the file or let the OS do it for you when your process terminates.
在现代文件系统上,EOF 不是字符,因此在完成写入文件时您不必发出它。当您的进程终止时,您只需关闭文件或让操作系统为您完成。
回答by Gene
Yes, you can manually add EOF to a file.
1) in Mac terminan, create a new file. touch filename.txt
是的,您可以手动将 EOF 添加到文件中。1) 在 Mac 终端中,创建一个新文件。touch filename.txt
2) Open the file in VI
2)在VI中打开文件
vi filename.txt
3) In Insert mode (hit i), type Control+V and then Control+D. Do not let go of the Control key on the Mac.
3) 在插入模式下(点击 i),输入 Control+V,然后输入 Control+D。不要松开 Mac 上的 Control 键。
Alternatively, if I want other ^NewLetters, like ^N^M^O^P, etc, I could do Contorl+V and then Control+NewLetter. So for example, to do ^O, hold down control, and then type V and O, then let go of Control.
或者,如果我想要其他 ^NewLetters,例如 ^N^M^O^P 等,我可以先执行 Contorl+V,然后再执行 Control+NewLetter。例如,要执行 ^O,请按住 control,然后键入 V 和 O,然后松开 Control。