Почему объявления строкового литерала C/C++ должны быть одной строкой?

Есть ли какая-либо конкретная причина, что многострочные строковые литералы, такие как следующее не разрешены в C++?

string script =
"
      Some
   Formatted
 String Literal
";

Я знаю, что многострочные строковые литералы могут быть созданы путем помещения обратной косой черты перед каждой новой строкой. Я пишу язык программирования (подобный C) и хотел бы позволить легкое создание многострочных строк (как в вышеупомянутом примере).

Есть ли какая-либо техническая причина предотвращения этого вида строкового литерала? Иначе я должен был бы использовать подобный Python строковый литерал с тройной кавычкой (который я не хочу делать):

string script =
"""
      Some
   Formatted
 String Literal
""";

Почему объявления строкового литерала C/C++ должны быть одной строкой?

17
задан Rizo 23 June 2010 в 09:41
поделиться

8 ответов

Следует учитывать, что C был написан не как язык программирования «Приложения», а как язык системного программирования. Было бы неправильно сказать, что он был разработан специально для переписывания Unix. Имея это в виду, не было ни EMACS, ни VIM, а ваши пользовательские интерфейсы были последовательными терминалами. Объявление многострочных строк могло бы показаться бессмысленным в системе, в которой не было многострочного текстового редактора. Более того, манипуляции со строками не будут главной проблемой для тех, кто хочет написать ОС в этот конкретный момент времени. Традиционный набор инструментов сценариев UNIX, таких как AWK и SED (среди МНОГИХ других), является свидетельством того факта, что они не использовали C для значительных манипуляций со строками.

Дополнительные соображения: в начале 70-х (когда был написан C) было обычным делом отправлять свои программы на ПЕРФОКАРТАх и возвращаться на следующий день, чтобы получить их. Потребовалось бы дополнительное время обработки для компиляции программы с многострочными строковыми литералами? Не совсем. На самом деле для компилятора может быть меньше работы. Но в большинстве случаев вы все равно собирались вернуться за ним на следующий день. Но никто из тех, кто заполнял перфокарту, не собирался вставлять большие объемы текста, который не нужен в их программах.

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

15
ответ дан 30 November 2019 в 10:13
поделиться

Другие упомянули несколько отличных обходных путей, я просто хотел устранить причину .

Причина проста в том, что C был создан в то время, когда обработка была в цене, а компиляторы должны были быть простыми и максимально быстрыми. В наши дни, если бы C был обновлен (я смотрю на вас, C1X ), вполне возможно делать именно то, что вы хотите. Однако это маловероятно. В основном по историческим причинам; такое изменение может потребовать обширного переписывания компиляторов и, вероятно, будет отклонено.

6
ответ дан 30 November 2019 в 10:13
поделиться

Препроцессор C работает построчно, но с лексическими токенами. Это означает, что препроцессор понимает, что «foo» является токеном. Однако, если бы C разрешил многострочные литералы, препроцессор оказался бы в затруднительном положении. Примите во внимание:

"foo
#ifdef BAR
bar
#endif
baz"

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

3
ответ дан 30 November 2019 в 10:13
поделиться

Я пишу язык программирования (похожий на C) и хотел бы позволить легко писать многострочные строки (как в приведенном выше примере).

Нет причин, по которым вы не могли бы создать язык программирования, позволяющий писать многострочные строки. Например, Vedit Macro Language (который является C-подобным языком сценариев для текстового редактора VEDIT) позволяет писать многострочные строки, например:

Reg_Set(1,"
      Some
   Formatted
 String Literal
")

Как определить синтаксис языка - решать вам.

1
ответ дан 30 November 2019 в 10:13
поделиться

Краткий ответ: «потому что грамматика запрещает многострочные строковые литералы». Я не знаю, есть ли для этого веская причина, кроме исторических причин.

Есть, конечно, способы обойти это. Вы можете использовать объединение строк:

const char* script = "\
      Some\n\
   Formatted\n\
 String Literal\n\
";

Если \ отображается как последний символ в строке, новая строка будет удалена во время предварительной обработки.

Или вы можете использовать конкатенацию строковых литералов:

const char* script = 
"      Some\n"
"   Formatted\n"
" String Literal\n";

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

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

const char* script = "      Some\n   Formatted\n  String Literal\n";
30
ответ дан 30 November 2019 в 10:13
поделиться

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

string script =
    "                \n"
    "       Some     \n"
    "    Formatted   \n"
    " String Literal ";
1
ответ дан 30 November 2019 в 10:13
поделиться

Фактически, вы можете разбить его следующим образом:

string script =
"\n"
"      Some\n"
"   Formatted\n"
" String Literal\n";

Смежные строковые литералы объединяются компилятор.

2
ответ дан 30 November 2019 в 10:13
поделиться

Вы также можете сделать:

string useMultiple =  "this" 
                      "is "
                      "a string in C."; 

Поместите один литерал за другим без каких-либо специальных символов.

0
ответ дан 30 November 2019 в 10:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: