2010-10-04 7 views
51

Nie mylić z jak podzielić ciąg parsowania mądry, np:
Split a string in C++?Dzielenie C++ Struny się w wielokrotne linie (Kod składni Nie analizowaniem)

Jestem nieco mylić, jak podzielić ciąg na wiele linii w C++.

Brzmi to jak proste pytanie, ale przyjąć następujący przykład:

#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; 
} 

Zdaję sobie sprawę, że mogę użyć metody std::stringappend(), ale zastanawiałem się, czy jest jakaś krótsza/bardziej elegancki (np więcej pythonopodobne, choć oczywiście potrójne cytaty itp. nie są obsługiwane w języku C++), sposób łamania łańcuchów w C++ na wiele linii w celu zapewnienia czytelności.

Jednym z miejsc, w którym byłoby to szczególnie pożądane, jest przekazywanie długich literałów do funkcji (na przykład zdania).

+2

Oto ciekawa ciekawostka: Lider w C++ nie dba o to, ile cytatów umieszczasz przed i po ciągu znaków z tylko dwoma wyjątkami. Liczba używanych cudzysłowów musi być nieparzysta i muszą one pasować po obu stronach. '" "" "" To jest poprawny łańcuch i zostanie sparsowany "" "" ". Jednak nie ma specjalnych właściwości nadanych tym ciągom znaków, one po prostu zachowują się jak pojedyncze cytaty. –

+0

Ciekawe dzięki za udostępnienie, że ... Czy jest jakiś przydatny cel? Możesz użyć tego jako subtelnego tagu dla różnych grup ciągów w kodzie do zewnętrznego analizowania przez skrypty perl/bash/python. To wszystko, o czym teraz myślę. :) –

+0

@ThomasAnthony To się właśnie dzieje, ponieważ traktuje cytaty na końcu jako grupę pustych ciągów i łączy je razem - to nie jest funkcja, to standardowe zachowanie C/C++ – texasflood

Odpowiedz

88

Nie umieszczaj niczego między strunami. Część etapu leksingu C++ polega na łączeniu sąsiednich literałów ciągów (nawet nad nowymi liniami i komentarzami) w jeden literał.

#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; 
} 

Pamiętaj, że jeśli chcesz przełamane w dosłownym, trzeba dodać, że sam:

#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; 
} 

Jeśli chcą mieszać #define d całkowitą stała się dosłowne, ty” będziesz musiał użyć kilka makra:

#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; 
} 

istnieje jakiś niesamowitość tam powodu sposobu funkcjonowania stringify operator procesor, więc trzeba dwa poziomy makro, aby uzyskać rzeczywistą wartość TWO należy przekształcić w literał łańcuchowy.

+0

Czy można mieszać w innych elementach, takich jak stała int ? Jeśli nie, w jaki sposób mogę je dodać? –

+0

@Jason: Co masz na myśli przez mieszanie w stałej int? – Eclipse

+0

moja_funkcja (arg_1, arg_2, "witaj świecie ten ciąg to" DWIE "linie długie!"); –

8

Czy oba są literałami? Oddzielenie dwóch ciągów znaków od białych znaków jest takie samo jak konkatenacja: "abc" "123" jest tożsamy ​​z "abc123". Dotyczy to zarówno prostych C, jak i C++.

+0

Ahhh takie proste. Dzięki! –

4

Nie wiem, czy jest to rozszerzenie w GCC, czy jest standardem, ale wydaje się, że można kontynuować literał ciągu, kończąc linię z ukośnikiem odwrotnym (tak jak większość typów linii może być przedłużona w tym dwór w C++, np. makro obejmujące wiele linii).

#include <iostream> 
#include <string> 

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

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

Ta dosłowna składnia zawiera sporo spacji między 'world' i' this' – SingleNegationElimination

+0

@TokenMacGuy: rzeczywiście tak jest, tego nie zauważyłem. Łatwo naprawić, jeśli przesuniesz drugą (i kolejne) linie do końca w lewo. Ale to naprawdę zepsułoby wygląd twojego wcięcia. – rmeador

+0

Tak, to było moje początkowe podejście, ale porzuciłem je z powodu problemów z wcięciami/odstępami @SingleNegationElimination. Warto jednak zauważyć. –