Чи є спосіб мати багаторядковий звичайний текст, постійні літерали в C ++, à la Perl? Можливо, якийсь трюк розбору з #include
файлом? Я не можу придумати одного, але хлопче, це було б добре. Я знаю, що це буде в C ++ 0x.
Чи є спосіб мати багаторядковий звичайний текст, постійні літерали в C ++, à la 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 (зі звичайними префіксами).
Я мушу зазначити, що послідовність аварійного виходу, 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 у відповіді @ unind, якщо одному не пощастило мати компілятор 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. Використовуючи бібліотеку підвищення, ви можете оголосити рядок як показано нижче
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. Якщо підвищення у вашому проекті недоступне, ви можете використовувати std :: string_view () в сучасному C ++.