Подтвердить что ты не робот

Каково значение '\n' в компиляторах C для старой Mac OS?

Фон:

В версиях Mac OS до версии 9 стандартное представление текстовых файлов использовало символ ASCII CR (символ возврата каретки), значение decimal 13, чтобы отметить конец строки.

Mac OS 10, в отличие от предыдущих выпусков, является UNIX-подобным и использует символ ASCII LF (строка), значение десятичное 10, чтобы отметить конец строки.

Вопрос: каковы значения символьных констант '\n' и '\r' в компиляторах C и С++ для выпусков ОС Mac до OS X?

Есть (по крайней мере) два возможных подхода, которые можно было бы предпринять:

  • Относитесь к '\n' как символ ASCII LF и преобразуйте его в и из CR на выходе и вводе из текстовых потоков (аналогично преобразованию между LF и CR-LF в системах Windows); или
  • Лечить '\n' как символ ASCII CR, который не требует преобразования на входе или выходе.

Были бы некоторые потенциальные проблемы со вторым подходом. Один из них заключается в том, что код, который предполагает '\n', может быть неудачным. (В любом случае такой код по своей природе не переносится.) Другое дело, что для '\r' все еще должно быть четкое значение, а в системе на основе ASCII CR - единственное разумное значение. И стандарт C не позволяет '\n' == '\r' (благодаря mafso для поиска цитаты, 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 к другому, но я надеюсь, что разработчики компилятора будут поддерживать согласованность друг с другом.

Чтобы быть ясным, я не спрашиваю, какое представление старых выпусков Mac OS используется для представления конца строки в текстовых файлах. Мой вопрос конкретно и только о значениях констант '\n' и '\r' в исходном коде C или С++. Я знаю, что печать '\n' (независимо от ее значения) в текстовый поток заставляет его преобразовываться в системное представление конца строки (в данном случае ASCII CR); это поведение требуется по стандарту C.

4b9b3361

Ответ 1

Значения констант символов \r и \n были такими же в средах Classic Mac OS, что и везде: \r был CR был ASCII 13 (0x0d); \n был LF, был ASCII 10 (0x0a). Единственное, что отличалось от Classic Mac OS, заключалось в том, что \r использовался как "стандартная" строка, заканчивающаяся текстовыми редакторами, так же как \n используется в системах UNIX или \r\n в системах DOS и Windows.

Вот скриншот простой тестовой программы, запущенной в Metrowerks CodeWarrior на Mac OS 9, например:

Example program running in CodeWarrior

Имейте в виду, что в системах Classic Mac OS не было общедоступной стандартной библиотеки C! Такие функции, как printf(), присутствовали только в составе специфичных для компилятора библиотек, таких как SIOUX для CodeWarrior, которые реализовали стандартный ввод-вывод C, путем записи вывода в окно с текстовым полем в нем. Таким образом, некоторые реализации стандартного ввода-вывода файлов могут выполнять автоматический перевод между \r и \n, что может быть тем, о чем вы думаете. (Многие системы Windows выполняют аналогичные действия для \r\n, если вы не передаете флаг "b" на fopen(), например.) Однако, конечно, ничего не было в Mac OS Toolbox.

Ответ 2

Я выполнил поиск и нашел эту страницу со старым обсуждением, в котором, в частности, можно найти следующее:

Реализация Metrowerks MacOS идет еще дальше обращая значение CR и LF в отношении '\ r' и '\n' escape файлы в i/o с участием файла, но не в любом другом контексте. Это означает, что если вы откроете ФАЙЛ или fstream в текстовом режиме, каждый '\ r' будет выводиться там как LF, а также каждый "\n", выводимый как CR, и тот же верно для ввода - двоичные соответствия escape-to-ASCII-двоичные обращаются вспять. Однако они не меняются вспять, как в памяти, например. с sprintf() в буфер или с std:: stringstream. Я нахожу это запутанным и, если не нестандартным, по крайней мере хуже других реализаций.

Оказывается, есть обходное решение с MSL - если вы открываете файл в двоичном режиме, тогда '\n' always == LF и '\ r' always == CR. Это то, что я хотел, но в получении эта информация я также получил много оправданий от люди там, что это был "стандартный" способ получить что я хотел, когда я чувствую, что это больше похоже на обходной путь за ошибку в их реализации. В конце концов, CR и LF являются 7-разрядными значениями ASCII, и я ожидаю, что смогу использовать их их стандартным способом с файлом, открытым в текстовом режиме.

(Ответ дает понять, что это действительно не является нарушением стандарта.)

Таким образом, очевидно, что была хотя бы одна реализация, которая использовала \n и \r с обычными значениями ASCII, но переводила их в (не двоичный) вывод файла (просто обменивая их).

Ответ 3

Спецификация на языке C:

5.2.2
...
2 Алфавитные escape-последовательности, представляющие неграфические символы в наборе символов выполнения, предназначены для создания действий на устройствах отображения следующим образом:
...
\n (новая строка) Перемещение активной позиции в исходное положение следующей строки. \ r (возврат каретки) Перемещение активной позиции в исходное положение текущей строки.

поэтому \n представляет соответствующий char в этом символьном кодировании... в ASCII есть LF char

Ответ 4

В старых компиляторах Mac роли \r и\n, где были обращены: у нас были '\n' == 13 и '\ r' == 10, а сегодня '\n' == 10 и '\ r '13. Очень весело во время переходного этапа. Напишите "\n" в файл со старым компилятором, прочитайте файл с новым компилятором и получите "\ r" (конечно, оба раза у вас на самом деле был номер 13).

Ответ 5

У меня нет старого компилятора Mac, чтобы проверить, следуют ли они этому, но числовое значение '\n' должно совпадать с символом новой строки ASCII (учитывая, что эти компиляторы использовали ASCII-совместимую кодировку как исполняемую кодировку, которые, как я считаю, они сделали). '\r' должно иметь то же числовое значение, что и возврат каретки ASCII.

Функции библиотеки или ОС, которые обрабатывают файлы текстового режима, отвечают за преобразование числового значения '\n' в зависимости от того, что использует ОС для завершения строк. Числовые значения этих символов во время выполнения полностью определяются набором символов выполнения.

Таким образом, поскольку мы все еще поддерживаем ASCII-кодирование, числовые значения должны быть такими же, как у классических компиляторов Mac.