簡體   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