繁体   English   中英

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

[英]What is the value of '\n' under C compilers for old Mac OS?

背景:

在最高版本为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字符,不需要对输入或输出进行转换。

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

在Mac OS N下编译和执行时,此C程序的输出是多少, 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编译器而异 - 但我希望编译器实现者能够保持彼此的一致性。

为了清楚起见,我不是要问Mac OS的旧版本用于表示文本文件中的行尾。 我的问题只是关于C或C ++源代码中常量'\\n''\\r'的值。 我知道将'\\n' (无论其值是什么)打印到文本流会导致它被转换为系统的行尾表示(在本例中为ASCII CR); C标准要求该行为。

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

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

在CodeWarrior中运行的示例程序

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

我做了一个搜索,发现这个页面有一个旧的讨论,特别是以下内容:

Metrowerks MacOS实现更进一步,通过颠倒CR和LF在涉及文件的i / o中的'\\ r'和'\\ n'转义的重要性,而不是在任何其他上下文中。 这意味着如果你在文本模式下打开一个FILE或fstream,每个'\\ r'将作为LF输出,每个'\\ n'输出为CR,输入也是如此 - 逃逸 - to-ASCII-binary对应关系是相反的。 但是它们在内存中并没有被反转,例如sprintf()到缓冲区或std :: stringstream。 我发现这令人困惑,如果不是非标准的话,至少比其他实现更糟糕。

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

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

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

C语言规范:

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM