“EOF”字符的十六进制代码在哪里?

Posted

技术标签:

【中文标题】“EOF”字符的十六进制代码在哪里?【英文标题】:Where is hex code of the "EOF" character? 【发布时间】:2014-09-19 10:30:03 【问题描述】:

据了解,在所有文件,特别是文本文件的末尾,EOFNULL 字符都有一个十六进制代码。而当我们想要编写程序并读取文本文件的内容时,我们会发送 read 函数,直到收到 EOF hexcode。

我的问题:我下载了一些工具来查看文本文件的十六进制视图。但我看不到 EOF(End Of File/NULL) 或 EOT(End Of Text)

的任何十六进制代码

ASCII/十六进制代码表:

这是十六进制查看器工具的输出:


注意:我的输入文件是一个文本文件,其内容是“EOF的十六进制代码在哪里?”

感谢您的时间和考虑。

【问题讨论】:

您在第一句话中的假设是错误的,在绝大多数情况下,文件中实际上不存在这样的字符。 EOF 是库提供的一个符号值,用于通知程序员您已到达文件末尾。操作系统不需要知道文件在哪里结束(或者更确切地说,它不会将此信息存储在文件本身中)。 @user657267 我编写了一个程序,在文本文件中搜索字符“A”。如果文本中没有“A”,请将文件移动到特殊目录。我想知道有什么办法可以欺骗我的程序吗?例如“在我的输入文本中间添加一个 NULL/EOF/EOT 十六进制代码”?谢谢。 不太可能。在 cmd.exe 中,^Z 被视为输入的结尾,因此如果您执行type whatever.txt 之类的操作,如果文件恰好包含一个,它会在遇到 ^Z 时中断,但这仅适用于 Windows 命令行。用于编程的 io 库应该很乐意将其解析为另一个字符。 ^Z 在 MS-DOS 文本文件中很常见,并且仍然适用于许多传输协议。我希望大多数 SO 用户不记得 MS-Kermit、xmoden、ymodem 等。它仍然是由 ind$file 生成的,而且是一件很麻烦的事。它会在 gedit 中抛出令人讨厌的消息,所以它确实存在。 @user657267 在某些情况下,操作系统可能不会从文件系统中读取,因此它需要提前知道文件大小,否则才能知道结束的位置。适用于流或原始。 【参考方案1】:

There is no such thing as a EOF character。操作系统确切地知道一个文件包含多少字节(这与权限、创建日期和名称等其他元数据一起存储),因此可以告诉程序试图读取一个十字节文件的第十一个字节:你已经已到达文件末尾,没有更多字节可读取。

事实上,诸如 getchar 之类的 C 函数返回的“EOF”值显式地是一个 int超出了一个字节的范围,因此它不可能存储在文件!

有时,某些文件格式坚持添加 NUL 终止符(可能是因为这就是字符串通常存储在 C 中的方式),尽管通常这些将多个记录分隔在单个文件中,而不是整个文件。而且这种装饰通常会使文件不被视为“文本文件”。

像 ETX 和 NUL 这样的 ASCII 代码可以追溯到电传打字机和朋友时代。 NUL 在 C 中用于 in-memory 字符串,但这与文件系统无关。

【讨论】:

我写了一个程序,在文本文件中搜索字符“A”。如果文本中没有“A”,请将文件移动到特殊目录。我想知道有什么办法可以欺骗我的程序吗?例如“在我的输入文本中间添加一个 NULL/EOF/EOT 十六进制代码”?谢谢。 @User1-St 取决于您如何读取文件并进行搜索(正如我所说,许多 C 函数认为 NUL 表示内存中字符串的结尾)但没有不可克服的困难。 如何欺骗我的程序。假设我的程序认为 Null 表示文件结束。在这种情况下,如果我在文件的十六进制视图中间添加一个“0x00”,程序会作弊吗? @User1-St 是的,几乎按照定义。这就是为什么你应该编写你的程序而不是做一些愚蠢的事情;-) :D 所以让我们写一个程序不要做一些傻事:))谢谢。【参考方案2】:

很久以前有一个文件结束标记,但它已经很多年没有在文件中使用了。

您可以使用以下方法在 Windows 上演示它的远处回声:

C:\>copy con junk.txt
Hello
Hello again
- Press <Ctrl> and <z>
C:\>dump junk.txt
junk.txt:
00000000  4865 6c6c 6f0d 0a48 656c 6c6f 2061 6761 Hello..Hello aga
00000010  696e 0d0a                               in..
C:\>

注意使用 Ctrl-Z 作为 EOT 标记。

但是,还要注意Ctrl-Z 不再出现在文件中 - 它曾经以0x1a 的形式出现,但仅在某些操作系统上出现,即使那样也不一致。

ETX (0x03) 的使用甚至在那些昏暗而遥远的时代之前就停止了。

【讨论】:

【参考方案3】:

没有EOF这样的东西。 EOF 只是文件读取函数返回的值,用于告诉您文件指针已到达文件末尾。

【讨论】:

我写了一个程序,在文本文件中搜索字符“A”。如果文本中没有“A”,请将文件移动到特殊目录。我想知道有什么办法可以欺骗我的程序吗?例如“在我的输入文本中间添加一个 NULL/EOF/EOT 十六进制代码”?谢谢。 只要你的程序运行在别人的机器上,他们就可以“欺骗”它。 怎么样?你的意思是他们可以给我的程序一个文本文件,内容中有“A”,而我​​的程序没有注意到吗? 如果你的程序在其他人的机器上运行并且他们真的想欺骗它,他们可以,即使使用像 OllyDbg 这样的调试器或通过挂钩 API 函数等,有很多方法可以欺骗程序。 我想知道有什么方法可以通过只更改文本文件来欺骗程序吗?假设他们无法在主机中安装或编辑任何东西(我的程序安装在其中)。【参考方案4】:

EOT 字节 (0x04) 至今仍被 unix tty 终端用来指示输入结束。您可以使用 Ctrl + D(即^D)来结束对 shell 或从标准输入读取的任何其他程序的输入。

但是,正如其他人所指出的,这与 EOF 不同,EOF 是一个条件而不是数据本身。

【讨论】:

【参考方案5】:

曾经甚至有不同的 EOF 字符(针对不同的操作系统)。再也见不到了。 (通常文件是 128 字节的块。)用于编码 PITA,就像现在的 BOM。

相反,仍然有一个 int read() 通常传递一个字节值,但对于 EOF 传递 -1。

NUL 字符是 C 中的字符串终止符。在 java 中,您可以在字符串中间使用 NUL 字符。为了与 C 合作,生成的 UTF-8 字节对 Unicode 字符 > 127 和 NUL 都使用多字节编码。

(其中一些可能已经知道。)

【讨论】:

UTF-8 not 不会为 NUL 生成多个字节。 ASCII 码 0 并不特殊,UTF-8 完全兼容 ASCII。与 C 更相关的是,没有 UTF-8 多字节序列包含 0 字节(或 any 字节 @delnan:所谓的Modified UTF-8也是对NUL使用多字节编码,给出0xC0、0x80。这样可以处理 C UTF-8 字符串中的 NUL 字符。 但修改后的 UTF-8 不是 UTF-8。它也很模糊。 en.wikipedia.org/wiki/UTF-8#Modified_UTF-8 提到了对象序列化。 DataOutputStream 也在 [writeUTF(docs.oracle.com/javase/7/docs/api/java/io/…) 中使用它。你是对的:官方 UTF-8 要求最短的多字节序列:0x00。 @User1-St:好的,这是我阅读的第四个答案也是您第四次添加该问题。不要那样做,这很烦人,而且违反了 SO 的政策。 “跟进”问题并不意味着在 cmets 中提出;应将它们编辑到您的帖子中(如果与原始问题相关 - 这不是)或单独询问。但大多数情况下,这很烦人。【参考方案6】:

在 7 位 Wintel 世界中,它是 0x1A 或 chr(26)。

它仍然常见于较旧的文本文件和档案中,并且仍然由某些文件传输协议产生。特别是从 BBS 系统下载的文本文件通常以该字符结尾。

对于旧系统还有其他此类标记值,并且需要不时预测 EOL(CR、LF、CR+LF)。

看到它仍在使用可能会令人烦恼,例如与 return(0) 处于同一级别。

【讨论】:

以上是关于“EOF”字符的十六进制代码在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

将带有前导“0x”的十六进制字符串转换为C++中的有符号短字符串?

在java中读取二进制文件,直到特定的“%% EOF”标记?

c语言中feof是啥意思

如何使用16进制文件编辑器Ultraedit

关于读文件的结束的判别方法(EOF和feof)以及区别

C语言怎么将超大的16进制数转换成10进制,这个16进制数是个大数,比如0x123456789ABCDEF12345这种