Возврат каретки как конец строки в файле c ++ - PullRequest
0 голосов
/ 05 ноября 2011

Я читал ISO 14882: 2003. Это говорит:

с-символ:
любой элемент исходного набора символов, кроме двойной кавычки ", обратной косой черты \ или символа новой строки избежать последовательности
универсальное имя персонажа

Теперь, что касается символа новой строки, я вижу проблему, когда окончание строки равно '\ r'
Я написал небольшую программу cpp:

#include <fstream>
#include <string>
int main()
{
    const char* program=""
        "#include <string>\n"
        "int main()\n"
        "{\n"
        "  std::string s;\n"
        "  //s=\"\r"
        "  //\r"
        "  //\r"
        "  //\r"
        "  //\";\n"
        "  s=\"\\xAE\\xfffactory\\xAE\\xffaction\";\n"
        "  return 0;\n"
        "}\n"
        ;
    std::ofstream file("file.cpp", std::ios_base::trunc);
    file << program;
    file.close();
    return 0;
}

В Windows file.cpp (как читается в редакторе VS):

#include <string>
int main()
{
  std::string s;
  //s="
  //
  //
  //
  //";
  s="\xAE\xfffactory\xAE\xffaction";
  return 0;
}

При компиляции file.cpp, триггеры VS и ошибка в строке 6 вместо строки 10.

В Linux file.cpp (как читается в emacs):

#include <string>
int main()
{
  std::string s;
  //s="^M  //^M  //^M  //^M  //";
  s="\xAE\xfffactory\xAE\xffaction";
  return 0;
}

Компиляция file.cpp с помощью gcc Я получаю сообщение об ошибке в строке 10, а не в строке 6.

Что я должен из этого сделать?

Ответы [ 4 ]

6 голосов
/ 05 ноября 2011

Вы должны сделать вывод, что:

  1. Редактор VS понимает любые окончания строк и отображает их в виде нескольких строк (ну, это известная функция).
  2. Компилятор MSVC не понимает \r окончания строк, поэтому фактически считает строку "; 6-й строкой.
  3. emacs не понимает \r окончания строк (по крайней мере по умолчанию), поэтому он показывает источник в одной строке.
  4. GCC понимает любые окончания строк, поэтому он не теряет счет.

Ах, также приведенная вами цитата из стандарта не имеет отношения. new-line там относится к исходному набору символов, а не к \r и \n в строках. Приведенное вами правило грамматики исключает строковый литерал, такой как:

const char* s = "some text, here comes 'new-line'
    ha ha ";
1 голос
/ 05 ноября 2011

Раздел 2.1 [lex.phases]. Первый этап перевода:

Физические символы исходного файла отображаются, в зависимости от реализации, в базовый исходный набор символов (ввод символов новой строки для индикаторов конца строки), если необходимо. ...

Другими словами, реализация может свободно использовать любое соглашение об окончании строки и превращать его в символы новой строки во время первой фазы перевода.

Практически, вы должны быть в безопасности, используя символ новой строки для окончания строки на любом современном компиляторе.

0 голосов
/ 05 ноября 2011

Теперь, что касается символа новой строки, я вижу проблему, когда окончание строки равно '\ r' ...

«\ r» - это возврат каретки, а не перевод строки - поэтому я не уверен, в чем проблема?

Windows решила создать магию, представляя \ r символами новой строки, но это не значит, что они на самом деле являются символами новой строки

0 голосов
/ 05 ноября 2011

В Windows и Linux используются разные соглашения о конце строки. В Linux конец строки равен 0x0A, а в Windows - 0x0D, 0x0A. Программы на C / C ++ сами по себе являются текстовыми файлами и часто взаимодействуют на разных платформах, если вы соответствуете текстовым соглашениям на платформе.

инструмент dos2unix(1) предназначен специально для этой задачи.

В качестве альтернативы, поскольку вы динамически генерируете этот код в своем собственном инструменте, вы можете предоставить опцию, которая указывает ему использовать один стиль окончания строки или другой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...