对于旧Mac OS,C编译器下'\ n'的值是多少?

时间:2014-07-31 18:04:26

标签: c++ c mac-classic

背景:

在最高版本为9的Mac OS版本中,文本文件的标准表示使用ASCII CR(回车)字符,值十进制13,以标记一行的结尾。

与早期版本不同,Mac OS 10与UNIX类似,并使用ASCII LF(换行符)值十进制值10来标记一行的结尾。

问题是,在OS X之前的Mac OS版本的C和C ++编译器中,字符常量'\n''\r'的值是什么?

可以采取(至少)两种可能的方法:

  1. '\n'视为ASCII LF字符,并在输出到CR和输入文本流时将其转换为CR(类似于Windows系统上LF和CR-LF之间的转换);或
  2. '\n'视为ASCII CR字符,不需要对输入或输出进行转换。
  3. 第二种方法可能存在一些潜在问题。一个是假定'\n'为LF的代码可能会失败。 (无论如何,这样的代码本质上是不可移植的。)另一个是'\r'仍需要一个不同的值,而在基于ASCII的系统上,CR是唯一明智的值。并且C标准不允许'\n' == '\r'(感谢mafso查找引文,5.2.2第3段),因此{{1}必须使用一些其他值}。

    在Mac OS N 下编译和执行此C程序的输出是什么, N 小于10?

    '\r'

    这个问题适用于C和C ++。我认为两者的答案都是一样的。

    答案也可能因C编译器而异 - 但我希望编译器实现者能够保持彼此的一致性。

    要明确的是,我不是要问Mac OS的旧版本用于表示文本文件中的行尾 。我的问题只是关于C或C ++源代码中常量#include <stdio.h> int main(void) { printf("'\\n' = %d\n", '\n'); printf("'\\r' = %d\n", '\r'); if ('\n' == '\r') { printf("Hmm, this could be a problem\n"); } } '\n'的值。我知道将'\r'(无论其值是什么)打印到文本流会导致它被转换为系统的行尾表示(在本例中为ASCII CR); C标准要求这种行为。

5 个答案:

答案 0 :(得分:45)

在经典Mac OS环境中,字符常量\r\n的值与其他地方完全相同:\r CR为ASCII 13({{1} }); 0x0d是LF是ASCII 10(\n)。 Classic Mac OS上唯一不同的是0x0a被用作&#34;标准&#34;以文本编辑器结尾的行,就像在UNIX系统上使用\r或在DOS和Windows系统上使用\n一样。

这是在Mac OS 9上运行Metrowerks CodeWarrior的简单测试程序的屏幕截图,例如:

Example program running in CodeWarrior

请记住,Classic Mac OS系统没有系统范围的标准C库!像\r\n这样的函数只作为编译器特定库的一部分出现,例如SIOUX for CodeWarrior,它通过将输出写入带有文本字段的窗口来实现C标准I / O.因此,标准文件I / O的某些实现可能在printf()\r之间执行了一些自动转换,这可能是您正在考虑的内容。 (例如,如果您没有将\n标记传递给\r\n,许多Windows系统会对"b"执行类似的操作。)Mac OS工具箱中肯定没有这样的内容但是。

答案 1 :(得分:5)

我做了一次搜索,发现this page有一个旧讨论,特别是以下内容:

  

Metrowerks MacOS实施更进了一步   扭转CR和LF的重要性   '\ r'和'\ n'在涉及文件的i / o中转义,但不是   在任何其他情况下。这意味着,如果您打开文件或   在文本模式下的fstream,每个'\ r'将在那里输出   一个LF以及每个'\ n'输出为CR,并且相同   输入是真的 - 转义为ASCII二进制对应关系   被逆转了。然而,它们并没有在内存中逆转,例如   使用sprintf()到缓冲区或使用std :: stringstream。   我发现这令人困惑,如果不是非标准,至少   比其他实现更糟糕。

     

事实证明MSL有一个解决方法 - 如果你打开   二进制模式下的文件然后'\ n'总是== LF和   '\ r'总是== CR。这是我想要的,但在获得   这些信息我也得到了很多理由   那边的人说这是获得的“标准”方式   我想要什么,当我觉得这更像是一种解决方法   对于他们实施中的错误。毕竟,CR和LF   是7位ASCII值,我希望能够使用   它们以标准方式在文本模式下打开文件。

(答案清楚地表明这确实 违反了标准。)

显然有至少一个实现,它使用\n\r与通常的ASCII值,但将它们转换为(非二进制)文件输出(通过只是交换它们。)

答案 2 :(得分:1)

C语言规范:

5.2.2
...
2表示执行字符集中的非图形字符的字母转义序列旨在按如下方式在显示设备上产生动作:
...
\ n(新行)将活动位置移动到下一行的初始位置 \ r \ n(回车)将活动位置移动到当前行的初始位置。

所以\n表示该字符编码中的相应字符...在ASCII中是LF字符

答案 3 :(得分:1)

在较旧的Mac编译器中,\ r和\ n的角色反转:我们有&#39; \ n&#39; == 13和&#39; \ r&#39; == 10,而今天&#39; \ n&#39; == 10和&#39; \ r&#39; == 13.过渡阶段非常有趣。写一个&#39; \ n&#39;到一个带有旧编译器的文件,用一个新的编译器读取文件,然后得到一个&#39; \ r&#39; (当然,这两次你实际上有一个数字13)。

答案 4 :(得分:1)

我没有旧的Mac编译器来检查它们是否遵循此规则,但'\n'的数值应与ASCII新行字符相同(假设这些编译器使用ASCII兼容编码作为执行编码,我相信他们这样做了。 '\r'应具有与ASCII回车相同的数值。

处理写入文本模式文件的库或OS函数负责将'\n'的数值转换为操作系统用于终止行的任何内容。运行时这些字符的数值完全由执行字符集决定。

因此,由于我们仍然是ASCII兼容的执行编码,因此数值应该与经典的Mac编译器相同。