我刚刚阅读了以下问题的答案删除文件末尾的换行符每个人都说删除最后一个字符。我的问题是,eof 字符不是最后一个吗?
答案1
ASCII 控制字符的定义来自 20 世纪 60 年代(实际上早于您可能认为的字符)网络)。并非所有这些控制字符都按照当时为电信设备定义的方式使用。
在类 Unix 系统上,不需要字符EOF
;没有使用。系统可以告诉应用程序一个文件有多少字节:
在某些其他系统(见于 VMS、DOS、Windows)上,control-Z 可能充当文件结束标记,因为较老的版本中系统无法告诉某些应用程序文件中有多少字节。
对于 VMS,限制是由于 C 运行时的工作方式造成的。汇编语言应用程序可以(并且确实)获得正确的文件大小。
Unix 系统中壳通常使用 control-D 告诉应用程序已到达输入(文件)末尾,但 control-D 并未存储在文件中。
在C中,EOF
是故意制造的-1
来表明它不是一个有效的字符。EOF
当检测到文件结束条件时,标准 I/O 返回,而不是特殊字符。
顺便说一句,文件不需要以新队(ASCII 换行)字符。文本编辑器可以处理所有可打印文本但缺少尾随换行符的文件。
答案2
正如前面的答案正确指出的那样,文件不会以文件结束字符结尾。但我认为答案和评论包含一些值得指出的不准确之处:
ASCII 字符集不包含确切的 EOF 字符。有几个“结束”控制字符:文本结束 (3)、传输结束 (4)、传输块结束 (23)、介质结束 (25)。文件分隔符 (28) 可能最接近 EOF 字符。代码 26 是“替换”,而不是 EOF。
Ctrl-D仅与终端输入相关。例如该命令
cat filea fileb filec > outfile
不涉及Ctrl- D。顺便说一句,您可以使用命令将终端 EOF 字符更改为Ctrl-之外的其他字符。Dstty
严格来说,Ctrl- D(或您更改为的任何内容)不是 EOF 键代码。它的作用是使
read
系统调用返回可用的输入,就像按 return 使 read 系统调用向调用者返回一行字符一样。按照惯例读取系统调用的返回值为零(即读取零个字符)表示文件结束条件。但是,输入文件不会自动关闭,并且如果输入来自终端,则不会将其置于“文件结束”状态。您可以编写一个程序,即使在“文件结束”之后仍继续从终端读取,并且读取调用可以为下一个输入行返回非零值。当某些输入已写入该行时,如果按下Ctrl-,则可以看出 eof 和 eol 字符之间的类比。D例如,如果您写入“abc”并按下Ctrl- Dread 调用返回,这次返回值为 3,并且“abc”存储在作为参数传递的缓冲区中。因为 read 不返回 0,所以根据上面的约定,这不会被解释为 EOF 条件。同样,按 return 使 read 调用返回整个输入行(包括换行符)。您可以使用以下命令尝试此
cat
操作:在该行上写一些字符,然后按Ctrl- D。您会看到字符回显给您并cat
等待更多输入。上述所有内容仅适用于终端处于“煮熟”模式时,而不是“原始”模式,在“原始”模式中,线路输入处理被最小化。在原始模式下,Ctrl-D 字符实际上被传递到输入缓冲区。
答案3
EOF 不是一个字符。这是一种状态,表示不再有字符可从文件流中读取。当您从终端输入 EOF 命令时,您是在向操作系统发出信号以关闭输入流,而不是输入特殊字符。