Czy jest jakiś sposób na posiadanie wieloliniowych tekstów stałych, literałów stałych w C ++, à la Perl? Może jakiś parsowanie sztuczki z #include
ingowaniem pliku? Nie mogę myśleć o jednym, ale chłopaku, byłoby miło. Wiem, że będzie w C ++ 0x.
c++
string-literals
rlbond
źródło
źródło
Odpowiedzi:
Cóż ... W pewnym sensie. Najłatwiej jest po prostu użyć faktu, że sąsiadujące literały łańcuchowe są łączone przez kompilator:
Wcięcie nie ma znaczenia, ponieważ nie ma go w cudzysłowie.
Możesz to również zrobić, o ile będziesz starał się uciec z wbudowanego nowego wiersza. Nieprzestrzeganie tego, podobnie jak moja pierwsza odpowiedź, nie spowoduje kompilacji:
Ponownie zwróć uwagę na te ukośniki odwrotne na końcu każdej linii, muszą znajdować się bezpośrednio przed końcem linii, uciekają od nowej linii w źródle, aby wszystko działało tak, jakby nowej linii nie było. W miejscach, w których wystąpiły ukośniki odwrotne, nie pojawiają się znaki nowej linii. W tym formularzu nie można oczywiście wciąć tekstu, ponieważ wcięcie stałoby się częścią łańcucha, zmieniając go losowymi spacjami.
źródło
W C ++ 11 masz surowe literały łańcuchowe. Coś jak tekst tutaj w powłokach i językach skryptowych, takich jak Python, Perl i Ruby.
Wszystkie spacje i wcięcia oraz znaki nowej linii w łańcuchu są zachowane.
Mogą to być również utf-8 | 16 | 32 lub wchar_t (ze zwykłymi prefiksami).
Powinienem zaznaczyć, że sekwencja ucieczki, V0G0N, nie jest tutaj tak naprawdę potrzebna. Jego obecność pozwoliłaby na umieszczenie) w sznurku. Innymi słowy, mógłbym to zrobić
(zwróć uwagę na dodatkowe cytaty), a ciąg powyżej nadal będzie poprawny. W przeciwnym razie równie dobrze mógłbym skorzystać
Pareny znajdujące się w cudzysłowie są nadal potrzebne.
źródło
#if 0
…,#endif
aby skomentować bloki kodu. Gniazda też.#define MULTILINE(...) #__VA_ARGS__
Zużywa wszystko między nawiasami.
Zastępuje dowolną liczbę następujących po sobie białych znaków jednym spacją.
źródło
\n
jeśli potrzebujesz nowych linii` (and hence
\ n) is copied literally, but
"jest konwertowany na\"
. WięcMULTILINE(1, "2" \3)
daje"1, \"2\" \3"
.Prawdopodobnie wygodnym sposobem wprowadzania ciągów wieloliniowych jest użycie makr. Działa to tylko wtedy, gdy cytaty i nawiasy są zrównoważone i nie zawiera przecinków „najwyższego poziomu”:
Skompilowany z gcc 4.6 lub g ++ 4.6, daje to:
[[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]
Zauważ, że
,
nie może być w ciągu, chyba że jest zawarty w nawiasie lub cudzysłowie. Pojedyncze cudzysłowy są możliwe, ale tworzą ostrzeżenia kompilatora.Edycja: Jak wspomniano w komentarzach,
#define MULTI_LINE_STRING(...) #__VA_ARGS__
umożliwia użycie,
.źródło
#define MULTILINE(...) #__VA_ARGS__
jeśli chcesz, aby Twój ciąg zawierał przecinki.\n
i\r
), co jest w niektórych przypadkach przydatne, a dla innych śmiertelne.Możesz także to zrobić:
źródło
char longString[] = R""""( This is a very long string )"""";
też działa dla mnie.Możesz po prostu to zrobić:
źródło
Ponieważ uncja doświadczenia jest warta mnóstwa teorii, wypróbowałem mały program testowy dla
MULTILINE
:Skompiluj ten fragment,
cpp -P -std=c++11 filename
aby go odtworzyć.Sztuczka
#__VA_ARGS__
polega na tym,__VA_ARGS__
że nie przetwarza separatora przecinków. Możesz więc przekazać go operatorowi naciągania. Wiodące i końcowe spacje są przycinane, a spacje (w tym nowe linie) między słowami są następnie kompresowane do pojedynczej spacji. Nawiasy muszą być zrównoważone. Myślę, że te niedociągnięcia wyjaśniają, dlaczego projektanci C ++ 11#__VA_ARGS__
dostrzegli potrzebę literałów surowych.źródło
Aby wyjaśnić nieco komentarz @ emsr w odpowiedzi @ unwind, jeśli nie ma się szczęścia, aby mieć kompilator C ++ 11 (powiedzmy GCC 4.2.1), i chcemy osadzić znaki nowej linii w ciągu (albo char * lub ciąg klasy), można napisać coś takiego:
To bardzo oczywiste, prawda, ale krótki komentarz @ emsr nie wyskoczył na mnie, gdy przeczytałem to po raz pierwszy, więc musiałem to odkryć dla siebie. Mam nadzieję, że zaoszczędziłem komuś jeszcze kilka minut.
źródło
źródło
Opcja 1. Korzystając z biblioteki boost, możesz zadeklarować ciąg znaków jak poniżej
Opcja 2. Jeśli boost nie jest dostępny w twoim projekcie, możesz użyć std :: string_view () we współczesnym C ++.
źródło