2009-10-10 19 views

Odpowiedz

9

Ta odpowiedź jest teraz nieaktualna dla nowoczesnego języka C++ - patrz sbi's answer dla nowoczesnego sposobu.

To jest najlepsze, co możesz zrobić:

std::cout << 
    "This is a\n" 
    "multiline\n" 
    "string.\n"; 

Nie tak wygodne, jak właściwego heredoc, ale nie straszne.

+8

Należy zauważyć, że nie jest to naprawdę żadna specjalna składnia ciągu wieloliniowego. Języki C i C++ będą łączyć literały łańcuchowe w kodzie źródłowym, więc jest to identyczne z 'std :: cout <<" Jest to \ nmultiline \ nstring. \ N ";' pod każdym względem (oprócz czytelności). –

0

Jeśli rozumiem zostanie poprawnie, wierzę chcesz to:

#include <iostream> 
... 
std::cout << std::endl << "yadayadayada" << std::endl; 
+1

Wcale się nie boję, chyba nie wyjaśniłem tego wyraźnie. Chcę coś, co może cout (lub wstawić do dowolnego strumienia) tekst uniknął UN. w PHP jest zrobione tak, jak powiedziałem (jestem pewien, że minęło trochę czasu), i wydrukuje wszystko dokładnie, dopóki nie znajdzie "END" w nowej linii, samodzielnie. właściwie możesz użyć dowolnego "deliminera", który chcesz zadeklarować, ale musi on kończyć się średnikiem i na własnej linii. –

1

Można zrobić tak:

std::cout << "First line\n" 
"second line\n" 
"third line\n" ; 

A to najlepsze, co można zrobić w C++.

+0

, więc odpowiedź brzmi, że to niemożliwe? –

0

Nie ma czegoś takiego jak HEREDOC w C++.

Można zrobić

cout << 
"yadayadayada" 
"yadayadayada" 
<< endl; 

To jest najlepszy można dostać. Ale wciąż ma ucieczki znaki specjalne jak \ "".

Sposób byłoby zawierać tekst jako ressource do pliku wykonywalnego lub załadować go z pliku zewnętrznego.

8

W C++, to zwykle nie jest uważany za styl kodowy, aby umieścić duże ilości danych w kodzie źródłowym, więc nie ma na to ochoty.

Zazwyczaj bardziej elastyczne jest umieszczanie tekstu w pliku zewnętrznym (takim jak plik tekstowy), a następnie nie jest on powiązany z skompilowanym plikiem wykonywalnym:

Jeśli chcesz, aby tekst był powiązany z plikiem wykonywalnym, wówczas (zależność ng na twojej platformie) możesz często użyć jakiejś formy pomocy zasobów lub asemblera z dyrektywą 'incbin', aby nadać nazwę obszarowi danych z żądanym tekstem.

Alternatywnie można użyć zewnętrznego narzędzia (takiego jak xxd -i) do kompilacji nazwanej tablicy w stylu C z danego pliku wejściowego. Wygenerowany plik można następnie skompilować z resztą kodu źródłowego.

+2

"W C++ nie jest zwykle uważane za styl kodowy, aby umieszczać duże ilości danych w kodzie źródłowym, więc nie ma na to ochoty." Nie sądzę, że to jest powód, dla którego nie ma na to ochoty, ale +1 dla 'xxd' –

+0

Mm, wciąż są pewne przypadki, w których ma to więcej sensu. Praca z shaderem to przyzwoity przypadek użycia; ogólnie rzecz biorąc nie chciałbyś osadzić swojego źródła cieniowania w swoim źródle programu (tak samo jak nie chciałbyś ogólnie zakodować wartości z twardego kodu), ale zrobienie tego dla "domyślnego" shadera może być dobrą praktyką, nie mówiąc o oddzieleniu GL testowanie od komplikacji z opcjami plików. –

+0

(Upłynął limit czasu edycji) - źródło shaderów wymagałoby cytatów i znaków nowej linii w wierszu bez HEREDOC lub alternatywy. Czy argumenty przeciwko HEREDOC dla C++ lub bardziej ogólne? IMHO ani literał łańcuchowy, ręczne łamanie linii, ani zewnętrzne preprocesory nie są "eleganckie", a nie "fantazyjne". Przepraszam, że chcę wykopać pocztę 8 lat w błocie. –

22

C++ 11 ma surowy string literals:

// this doesn't have '\n', but '\\' and 'n' 
R"(yada"yadayada\n)" 

A jeśli potrzebujesz tych nawiasów, można to zrobić również za pomocą co chcesz dla tokenu końcowego:

// the following will be "(yada)(yada)(yada)" 
R"END((yada)(yada)(yada))END" 

go działa również z osadzonymi nowymi liniami:

// the following will be "\n(yada)\n(yada)\n(yada)\n" 
R"END(
(yada) 
(yada) 
(yada) 
)END" 
+0

Ale myślę, że nadal nie pozwoli na osadzanie nowych linii. – me22

+0

Czy istnieje sposób użycia zmiennych wewnątrz 'literałów łańcuchowych'? – Lanti

+2

@Lanti: Oczywistą odpowiedzią jest nie, ponieważ termin "dosłowny" oznacza, że ​​wartość jest interpretowana _literalnie_. Ale podejrzewam, że twoje pytanie można poprawić poprzez faktyczne stwierdzenie, co chcesz zrobić. – sbi

0

Cięcie na końcu linii oznacza, że ​​następna linia jest kontynuacją na ciąg.Prowadzi to do alternatywnej składni, które mogą lub nie mogą preferować nad innymi sugestiami:

std::cout << "\ 
This is a\n\ 
multiline\n\ 
string.\ 
"; 

Zalety: nie trzeba owinąć każdą linię w cudzysłowie; podczas importowania tekstu z jakiegoś innego źródła wystarczy edytować jeden koniec każdej linii, a nie oba końce (bardziej makro); i widać dokładnie, jak będzie wyglądać wynikowy ciąg znaków, w tym spacje wiodące.

Wady: nadal musisz jawnie dodawać znaki \ n dla znaków nowej linii i nie lubię tracić zdolności do wcięcia mojego kodu ładnie i ładnie. Składnia HEREDOC również cierpi z powodu tej cechy, więc może to ci nie przeszkadza.

Osobiście nie jest to składnia, którą lubię.

+0

Wspomniałem o tym gdzie indziej w komentarzach - czy jest to implementacja zachowania nowej linii// OS, czy coś w tym stylu? Drukuję 'R" (jako df) ", a wynik zawiera' \ n''. Wydaje mi się, że jestem tutaj osobliwym człowiekiem. (C++ 11, GCC na Linux x64, jeśli to ma znaczenie). –

Powiązane problemy