如何在C中打印.txt中的CR和LF字符?

问题描述 投票:0回答:1

我有一个包含 100 行代码的 .txt 文件。将 fseek() 和 ftell() 函数提供的文件大小与字符数进行比较后,我观察到文件大小有 198 字节的差异 - 恰好是行数的 2 倍(100 行减去最后一行),这表明Windows 使用 2 个字符来标识每一行(通过可靠的 Wiki 搜索确认)。

我尝试使用 getc() 打印出行尾的 2 个字符,但只能打印出 LF(ASCII 代码 10)字符。下一个字符只是文件中的下一个字符 - 任何地方都没有 RF 迹象。

是否可以访问 CR 字符并在终端中将其打印出来? .txt 文件在 Linux 上处理得“更好”吗?仅使用 ([换行符] - 以防万一它在堆栈溢出格式中丢失)来识别行尾?

c ascii txt
1个回答
1
投票

是否可以访问 CR 字符并在终端中打印出来?

C

FILE
s 可以以文本或二进制模式打开。

  • 在文本模式下,主机环境的文本约定和以换行符(单独)作为行分隔符的字符流的 C 内部模型之间可能存在双向转换。

    这在过去更为重要,当时文本文件的本地约定相当广泛。如今,常见主机环境之间的主要区别是行终止约定 - Windows 使用 CR/LF 对,而大多数其他人只使用 LF。

  • 在二进制模式下,没有翻译,只是原始字节流。

    这种区别在大多数常见操作环境中没有太大区别,但在 Windows 上,以二进制模式打开文件可以避免 CR/LF 转换。

在 Windows 和 Unix(包括 Linux 和 Mac)上,文本与二进制性质是文件内容的解释问题,而不是文件的固有特征。如果您想显式处理每个 CR/LF 终止符的两个字节,则意味着您希望将文件视为二进制文件。当你打开它时指定:

    FILE *my_file = fopen("example.txt", "rb");

特别注意打开模式下的b

"rb"
。这就是指定二进制模式的内容。默认为文本模式。

以这种方式打开文件后,您将能够显式读取 CR 字符。如果您打开一个文件以二进制模式写入,那么您也需要显式地写入那些 CR 字符,如果您实际上需要它们的话。

但另一种答案是,通常,如果您想根据本地约定处理文本文件,那么您可以忽略其中的大部分内容。以文本模式打开文本文件。无论传统的行终止符是什么,都将作为单个 LF 呈现给您的程序。由于标准输出默认以文本模式打开,因此当您转身并将 LF 回显到标准输出时,它将被转换为另一个方向 - 如果这是主机环境的约定,则转换为 CR/LF。

.txt 文件在 Linux 上处理得“更好”吗?仅使用 ([换行符] - 以防万一它在堆栈溢出格式中丢失)来识别行尾?

名称以

.txt
结尾的文件应根据其内容进行适当处理。任何地方。

如果可以通过扩展名来表达该文件符合主机环境的文本约定(无论是 Windows、Linux 还是其他环境),那么应该以文本模式读取和写入该文件。相同的 C 源代码将在 Linux 上完成此操作,就像在 Windows 上一样。该代码会将换行符(单独)识别为行终止符。

如果扩展名应该被理解为符合某些特定文本约定的文件,例如Windows',那么应该根据这些约定适当地处理此类文件。如果您希望代码可移植,这可能意味着以二进制模式访问它们。在 Linux 上读取 Windows 文本文件并像在 Windows 上解释它们一样解释它们需要手动过滤掉每个 CR/LF 对的 CR。

或者您是想比较 Windows 和 Linux 文本约定吗?

使用 CR/LF 行终止符而不是单字符终止符是 Windows 的遗留功能,我认为这也是 MS-DOS 之前的遗留功能。它来自于行式打印机终端时代,其中 CR 和 LF 控制字符引发了一些此类终端的单独物理操作——分别将打印头返回到第一列,并将纸张前进到下一行。它们仍然可以在视频终端上产生不同的操作,具体取决于终端配置。但这些都不是将两字节行终止符合并到文本文件格式中的特别有力的理由。

© www.soinside.com 2019 - 2024. All rights reserved.