Розбиття рядків C ++ на кілька рядків (синтаксис коду, не розбір)


77

Не слід плутати з тим, як розділити рядок розумно, наприклад:
Розділити рядок у C ++?

Я трохи заплутаний щодо того, як розділити рядок на кілька рядків у C ++.

Це звучить як просте запитання, але візьмемо такий приклад:

#include <iostream>
#include <string>
main() {
  //Gives error
  std::string my_val ="Hello world, this is an overly long string to have" +
    " on just one line";
  std::cout << "My Val is : " << my_val << std::endl;

  //Gives error
  std::string my_val ="Hello world, this is an overly long string to have" &
    " on just one line";  
  std::cout << "My Val is : " << my_val << std::endl;
}

Я усвідомлюю, що міг би використати std::string append()метод, але мені було цікаво, чи є якийсь коротший / елегантніший (наприклад, більше схожий на пітон, хоча очевидно, що потрійні лапки тощо не підтримуються в c ++), щоб розбити рядки в c ++ на кілька рядків заради читабельності.

Одне з таких місць, де це було б особливо бажано, це коли ви передаєте довгі рядкові літерали функції (наприклад, реченню).


2
Ось цікавий шматок: лексеру С ++ насправді не важливо, скільки лапок ви розміщуєте до і після рядка, лише за двома винятками. Кількість цитат, які ви використовуєте, має бути непарною, і вони повинні збігатися з обох сторін. """"" This is a valid string and will be parsed """"". Однак особливих властивостей, наданих цим рядкам, немає, вони просто поводяться як одинарні лапки.
— Томас Ентоні

Цікава подяка, що поділилися цим ... чи є для цього якась корисна мета? Можливо, ви зможете використовувати це як тонкий тег для різних груп рядків у коді для зовнішнього аналізу за сценаріями perl / bash / python. Це приблизно все, що я зараз можу придумати. :)
— Джейсон Р. Мік

@ThomasAnthony Це просто трапляється, тому що він буде розглядати цитати навколо кінця як купу порожніх рядків і об'єднувати їх разом - це не особливість, це стандартна поведінка C / C ++
— texasflood

Відповіді:


126

Не кладіть нічого між рядків. Частиною етапу лексингу на C ++ є поєднання сусідніх рядкових літералів (навіть над новими рядками та коментарями) в один літерал.

#include <iostream>
#include <string>
main() {
  std::string my_val ="Hello world, this is an overly long string to have" 
    " on just one line";
  std::cout << "My Val is : " << my_val << std::endl;
}

Зверніть увагу, що якщо вам потрібен новий рядок у літералі, вам доведеться додати це самостійно:

#include <iostream>
#include <string>
main() {
  std::string my_val ="This string gets displayed over\n" 
    "two lines when sent to cout.";
  std::cout << "My Val is : " << my_val << std::endl;
}

Якщо ви хочете змішати #defineконстанту d цілого числа в літералі, вам доведеться використовувати деякі макроси:

#include <iostream>
using namespace std;

#define TWO 2
#define XSTRINGIFY(s) #s
#define STRINGIFY(s) XSTRINGIFY(s)

int main(int argc, char* argv[])
{
    std::cout << "abc"   // Outputs "abc2DEF"
        STRINGIFY(TWO)
        "DEF" << endl;
    std::cout << "abc"   // Outputs "abcTWODEF"
        XSTRINGIFY(TWO) 
        "DEF" << endl;
}

Тут є якась дивина через те, як працює оператор процесора stringify, тому вам потрібні два рівні макросів, щоб отримати фактичне значення, TWOяке потрібно зробити з рядкового літералу.


Чи можете ви змішувати інші предмети, як int константу? Якщо ні, як їх додати?
— Джейсон Р. Мік,

@ Джейсон: Що ви маєте на увазі під змішуванням в константі int?
— Eclipse,

моя_функція (arg_1, arg_2, "привіт світ, цей рядок має" ДВА "рядки!");
— Джейсон Р. Мік,

4
Поєднання рядкових літералів є фактичною частиною лексичної фази (не попереднього процесора), оскільки поділ рядків, подібний до цього, визначається як частина мови.
— Мартін Йорк,

1
@Jason, з вашого подальшого запитання, схоже, вам потрібно щось на зразок STRINGIFYмакросу вище.
— Затемнення

10

Вони обоє буквально? Відокремлення двох рядкових літералів з пробілами те саме, що і конкатенація: "abc" "123"те саме, що "abc123". Це стосується як прямої С, так і С ++.


7

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

#include <iostream>
#include <string>

int main ()
{
    std::string str = "hello world\
    this seems to work";

    std::cout << str;
    return 0;
}

4
Цей буквальний синтаксис містить досить багато пробілів між worldіthis
— SingleNegationElimination

@TokenMacGuy: справді так, я цього не помічав. Це досить легко виправити, якщо перемістити другий (і наступні) рядки до кінця вліво. Але це справді зіпсує вигляд вашого відступу.
— rmeador

Так, це був мій початковий підхід, але я відмовився від нього через проблеми з відступами / інтервалами @SingleNegationElimination контури. Хороший зауваження, хоча.
— Джейсон Р. Мік,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.