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

背景:

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

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

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

至less有两种可能的方法可以采取:

  1. '\n'视为ASCII LF字符,并将其转换为从CR输出到文本stream的input(类似于Windows系统上的LF和CR-LF之间的转换); 要么
  2. '\n'视为ASCII CR字符,不需要在input或输出上进行转换。

第二种方法会有一些潜在的问题。 一个是假设'\n'是LF的代码可能会失败。 (无论如何,这样的代码本质上是不可移植的。)另一个是对'\r'仍然需要一个不同的值,而在基于ASCII的系统上,CR是唯一合理的值。 而C标准不允许'\n' == '\r' (感谢mafsofind引用,5.2.2第3段),所以其他一些值将被用于'\r'

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

 #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"); } } 

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

从一个C编译器到另一个C编译器的答案也不尽相同 – 但我希望编译器实现者能保持一致性。

要清楚的是,我并不是问Mac OS的旧版本用于代表文本文件中的行结尾。 我的问题是关于C或C ++源代码中常量'\n''\r'具体和唯一的值。 我知道打印'\n' (无论它的值是什么)到一个文本stream导致它被转换为系统的行尾表示(在这种情况下,ASCII CR); 该行为是C标准所要求的。

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

下面是在Mac OS 9上运行在Metrowerks CodeWarrior上的简单testing程序的截图,例如:

在CodeWarrior中运行的示例程序

请记住,经典的Mac OS系统没有全系统的标准C库! 像printf()这样的printf()只是作为CodeWarrior的SIOUX这样的特定于编译器的库的一部分存在的,CodeWarrior通过将输出写入带有文本字段的窗口来实现C标准I / O。 因此,标准文件I / O的某些实现可能已经在\r\n之间执行了一些自动转换,这可能就是您所想的。 (例如,如果你没有将"b"标志传递给fopen() ,许多Windows系统都会为\r\n做类似的事情。)Mac OS Toolbox当然没有这样的事情。

我做了一个search,发现这个页面的老讨论,特别是可以发现以下内容:

Metrowerks MacOS的实现更进一步,通过颠倒CR和LF在涉及文件的I / O中的'\ r'和'\ n'转义的意义,而不是在任何其他上下文中。 这意味着如果你在文本模式下打开一个FILE或fstream,那么每个'\ r'将以LF的forms输出,每个'\ n'以CRforms输出,input也是如此 – to-ASCII-binary对应关系相反。 它们在内存中不会被逆转,例如,使用sprintf()到缓冲区或使用std :: stringstream。 我觉得这很混乱,如果不是非标准的,至less比其他的实现更糟糕。

事实certificate,MSL有一个解决方法 – 如果你以二进制模式打开文件,那么'\ n'总是== LF,'\ r'总是== CR。 这是我想要的,但是在获得这些信息的时候,我也从那里的人那里得到了很多理由,那就是这是获得我想要的“标准”方式,当我觉得这更像是一个解决方法实现。 毕竟,CR和LF是7位ASCII值,我希望能够以文本模式打开的文件以标准方式使用它们。

(答案明确表示这确实违反标准。)

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

C语言规范:

5.2.2

2表示执行字符集中的非字符字符的字母转义序列用于在显示设备上产生如下动作:

\ n(新行)将活动位置移动到下一行的起始位置。
\ r(回车)将活动位置移动到当前行的初始位置。

所以\n表示该字符编码中的适当的字符…在ASCII中是LF字符

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

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

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

在旧的Mac编译器上,\ r和\ n的作用相反:我们有'\ n'== 13和'\ r'== 10,而今天\ n'== 10和'\ r'== 13.过渡阶段非常有趣。 用一个旧的编译器写一个'\ n'到一个文件中,用一个新的编译器读取这个文件,然后得到一个'\ r'(当然,这两次实际上都是13)。