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

Фон:

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

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

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

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

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

Со вторым подходом могут возникнуть некоторые проблемы. Одним из них является тот код, который предполагает '\n' Это НЧ может потерпеть неудачу. (Такой код по сути своей непереносим.) Другое дело, что все еще должно быть отдельное значение для '\r'и в системе на основе ASCII CR является единственным разумным значением. И стандарт С не позволяет '\n' == '\r' (спасибо mafso за нахождение цитаты, пункт 5.2.2), поэтому некоторые Другой значение должно быть использовано для '\r',

Каков вывод этой программы на С при компиляции и исполнении под 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 к другому, но я надеюсь, что разработчики компилятора будут поддерживать согласованность друг с другом.

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

45

Решение

Значения символьных констант \r а также \n было то же самое в классической среде 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, например:

Пример программы, работающей в CodeWarrior

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

45

Другие решения

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

Внедрение Metrowerks MacOS делает шаг вперед
обращая вспять значение CR и LF в отношении
‘\ r’ и ‘\ n’ экранируются при вводе / выводе с использованием файла, но не
в любом другом контексте. Это означает, что если вы откроете файл или
fstream в текстовом режиме, каждый ‘\ r’ будет выводиться там как
LF, а также каждый ‘\ n’, выводимый как CR, и тот же
верно для ввода — escape-ASCII-бинарные соответствия
перевернуты Однако они не обращаются вспять в памяти, например,
с помощью sprintf () в буфер или с помощью std :: stringstream.
Я нахожу это запутанным и, если не нестандартным, по крайней мере
хуже, чем другие реализации.

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

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

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

5

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

5.2.2



2 Буквенные escape-последовательности, представляющие неграфические символы в наборе исполнительных символов, предназначены для выполнения действий на устройствах отображения следующим образом:

\ n (новая строка) Перемещает активную позицию в начальную позицию следующей строки.
\ r (возврат каретки) Перемещает активную позицию в начальную позицию текущей строки.

так \n представляет соответствующий символ в этой кодировке символов … в ASCII это LF голец

1

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

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

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

1

В старых компиляторах Mac роли \ r и \ n были поменяны местами: у нас было «\ n» == 13 и «\ r» == 10, а сегодня «\ n» == 10 и «\ r» == 13. Большое удовольствие на переходном этапе. Запишите ‘\ n’ в файл со старым компилятором, прочитайте файл с новым компилятором и получите ‘\ r’ (конечно, оба раза у вас действительно было число 13).

1
По вопросам рекламы [email protected]