Есть ли способ иметь многострочные обычные текстовые константные литералы в C ++, как в Perl? Может быть, какая-то хитрость при разборе #include
файла? Я не могу думать об этом, но мальчик, это было бы хорошо. Я знаю, что это будет в C ++ 0x.
Есть ли способ иметь многострочные обычные текстовые константные литералы в C ++, как в Perl? Может быть, какая-то хитрость при разборе #include
файла? Я не могу думать об этом, но мальчик, это было бы хорошо. Я знаю, что это будет в C ++ 0x.
Ответы:
Ну ... вроде. Проще всего использовать тот факт, что смежные строковые литералы объединяются компилятором:
const char *text =
"This text is pretty long, but will be "
"concatenated into just a single string. "
"The disadvantage is that you have to quote "
"each part, and newlines must be literal as "
"usual.";
Отступ не имеет значения, поскольку он не находится внутри кавычек.
Вы также можете сделать это до тех пор, пока вы позаботитесь о том, чтобы избежать встроенного перевода строки. Невыполнение этого требования, как и мой первый ответ, не будет компилироваться:
const char * text2 = "Здесь, с другой стороны, я сошел с ума \ и действительно пусть буквальный занимает несколько строк, \ не утруждая себя цитированием каждой строки \ содержание. Это работает, но вы не можете сделать отступ. ";
Опять же, обратите внимание на эти обратные слеши в конце каждой строки, они должны быть непосредственно перед концом строки, они экранируют символ новой строки в источнике, чтобы все действовало так, как будто строки не было. Вы не получаете переводы строки в местах, где у вас были обратные слеши. С помощью этой формы вы, очевидно, не сможете сделать отступ для текста, так как отступ станет частью строки, заключив ее в произвольные пробелы.
В C ++ 11 у вас есть необработанные строковые литералы. Вроде как здесь текст в оболочках и языках сценариев, таких как Python и Perl и Ruby.
const char * vogon_poem = R"V0G0N(
O freddled gruntbuggly thy micturations are to me
As plured gabbleblochits on a lurgid bee.
Groop, I implore thee my foonting turlingdromes.
And hooptiously drangle me with crinkly bindlewurdles,
Or I will rend thee in the gobberwarts with my blurlecruncheon, see if I don't.
(by Prostetnic Vogon Jeltz; see p. 56/57)
)V0G0N";
Все пробелы и отступы и новые строки в строке сохраняются.
Это также могут быть utf-8 | 16 | 32 или wchar_t (с обычными префиксами).
Я должен указать, что escape-последовательность V0G0N здесь на самом деле не нужна. Его присутствие позволило бы поместить "внутри строки". Другими словами, я мог бы поставить
"(by Prostetnic Vogon Jeltz; see p. 56/57)"
(обратите внимание на дополнительные кавычки) и приведенная выше строка все равно будет правильной. В противном случае я мог бы так же хорошо использовать
const char * vogon_poem = R"( ... )";
Парены внутри цитат все еще нужны.
#if 0
…, #endif
чтобы закомментировать блоки кода. Гнезда тоже.
#define MULTILINE(...) #__VA_ARGS__
Потребляет все между скобками.
Заменяет любое количество последовательных пробельных символов на один пробел.
\n
если вам нужны новые строки
` (and hence
\ n ) is copied literally, but
"` конвертируется в \"
. Так что MULTILINE(1, "2" \3)
получается "1, \"2\" \3"
.
Вероятно, удобный способ ввода многострочных строк - использование макросов. Это работает, только если кавычки и круглые скобки сбалансированы и не содержат запятых «верхнего уровня»:
#define MULTI_LINE_STRING(a) #a
const char *text = MULTI_LINE_STRING(
Using this trick(,) you don't need to use quotes.
Though newlines and multiple white spaces
will be replaced by a single whitespace.
);
printf("[[%s]]\n",text);
Скомпилированный с gcc 4.6 или g ++ 4.6, он производит: [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]
Обратите внимание, что ,
в строке не может быть строк, если они не содержатся в скобках или кавычках. Одинарные кавычки возможны, но создают предупреждения компилятора.
Изменить: как уже упоминалось в комментариях, #define MULTI_LINE_STRING(...) #__VA_ARGS__
позволяет использовать ,
.
#define MULTILINE(...) #__VA_ARGS__
если вы хотите, чтобы ваша строка содержала запятые.
\n
и \r
), что довольно удобно для некоторых случаев и фатально для других.
Вы также можете сделать это:
const char *longString = R""""(
This is
a very
long
string
)"""";
char longString[] = R""""( This is a very long string )"""";
работает и для меня.
Поскольку унция опыта стоит тонны теории, я попробовал небольшую тестовую программу для MULTILINE
:
#define MULTILINE(...) #__VA_ARGS__
const char *mstr[] =
{
MULTILINE(1, 2, 3), // "1, 2, 3"
MULTILINE(1,2,3), // "1,2,3"
MULTILINE(1 , 2 , 3), // "1 , 2 , 3"
MULTILINE( 1 , 2 , 3 ), // "1 , 2 , 3"
MULTILINE((1, 2, 3)), // "(1, 2, 3)"
MULTILINE(1
2
3), // "1 2 3"
MULTILINE(1\n2\n3\n), // "1\n2\n3\n"
MULTILINE(1\n
2\n
3\n), // "1\n 2\n 3\n"
MULTILINE(1, "2" \3) // "1, \"2\" \3"
};
Скомпилируйте этот фрагмент cpp -P -std=c++11 filename
для воспроизведения.
Хитрость в #__VA_ARGS__
том, что __VA_ARGS__
не обрабатывается запятая. Таким образом, вы можете передать его оператору строки. Начальные и конечные пробелы обрезаются, а пробелы (включая переводы строк) между словами сжимаются в один пробел. Круглые скобки должны быть сбалансированы. Я думаю, что эти недостатки объясняют, почему разработчики C ++ 11, несмотря на это #__VA_ARGS__
, увидели необходимость в необработанных строковых литералах.
Просто чтобы немного разъяснить комментарий @ emsr в ответе @ unwind, если кому-то не повезло иметь компилятор C ++ 11 (скажем, GCC 4.2.1), и кто-то хочет встроить строки в строку (либо char * или строка класса), можно написать что-то вроде этого:
const char *text =
"This text is pretty long, but will be\n"
"concatenated into just a single string.\n"
"The disadvantage is that you have to quote\n"
"each part, and newlines must be literal as\n"
"usual.";
Совершенно очевидно, правда, но короткий комментарий @ emsr не выскочил на меня, когда я прочитал это в первый раз, поэтому мне пришлось открыть это для себя. Надеюсь, я спас кого-то еще несколько минут.
// C++11.
std::string index_html=R"html(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>VIPSDK MONITOR</title>
<meta http-equiv="refresh" content="10">
</head>
<style type="text/css">
</style>
</html>
)html";
Вариант 1. Используя библиотеку Boost, вы можете объявить строку, как показано ниже
const boost::string_view helpText = "This is very long help text.\n"
"Also more text is here\n"
"And here\n"
// Pass help text here
setHelpText(helpText);
Вариант 2. Если boost не доступен в вашем проекте, вы можете использовать std :: string_view () в современном C ++.