2012-11-01 22 views
17

Potrzebuję podzielić ciąg według linii. kiedyś zrobić w następujący sposób: ". Jesteśmy jednym \ nyes jesteśmy"C++ split string po linii

int doSegment(char *sentence, int segNum) 
{ 
assert(pSegmenter != NULL); 
Logger &log = Logger::getLogger(); 
char delims[] = "\n"; 
char *line = NULL; 
if (sentence != NULL) 
{ 
    line = strtok(sentence, delims); 
    while(line != NULL) 
    { 
     cout << line << endl; 
     line = strtok(NULL, delims); 
    } 
} 
else 
{ 
    log.error("...."); 
} 
return 0; 
} 

I wejście i wywołaj metodę doSegment. Ale po debugowaniu znalazłem parametr zdanie: "jesteśmy jednym. \\ ny my jesteśmy", a podział się nie powiódł. Czy ktoś może mi powiedzieć, dlaczego tak się stało i co powinienem zrobić. Czy jest jeszcze możliwe, aby podzielić ciąg w C++. dzięki !

+2

Proponuję za pomocą prawdziwego C++ - spojrzeć na std :: getline –

+1

trzeba dokonać pewnych zmian o wejściu. Nie funkcja podziału. – halfelf

+0

Uważaj na 'strtok', ponieważ modyfikuje ciąg, który ci przekazujesz. –

Odpowiedz

35

Chciałbym użyć std :: getline lub std :: string :: find, aby przejść przez ciąg. poniżej kod demonstruje funkcja getline

int doSegment(char *sentence) 
{ 
    std::stringstream ss(sentence); 
    std::string to; 

    if (sentence != NULL) 
    { 
    while(std::getline(ss,to,'\n')){ 
     cout << to <<endl; 
    } 
    } 

return 0; 
} 
+0

jeszcze jedno pytanie. Nie byłam pewna, czy łańcuch struny musi się zamknąć. – wangzhiju

+4

to zmienna lokalna, ulegnie zniszczeniu, jeśli wydostanie się z doSegment. – billz

9

Możesz zadzwonić pod numer std::string::find w pętlę i użyć std::string::substr.

std::vector<std::string> split_string(const std::string& str, 
             const std::string& delimiter) 
{ 
    std::vector<std::string> strings; 

    std::string::size_type pos = 0; 
    std::string::size_type prev = 0; 
    while ((pos = str.find(delimiter, prev)) != std::string::npos) 
    { 
     strings.push_back(str.substr(prev, pos - prev)); 
     prev = pos + 1; 
    } 

    // To get the last substring (or only, if delimiter is not found) 
    strings.push_back(str.substr(prev)); 

    return strings; 
} 

Zobacz przykład here.

+3

Jeśli używasz separatora, który ma więcej niż jeden znak, tak jak ja, będziesz chciał zmienić "prev = pos + 1;" wiersz do "prev = pos + delimiter.size();" zamiast. W przeciwnym razie pozostałe znaki pozostaną na początku następnego elementu w wektorze. –

0
#include <iostream> 
#include <string> 
#include <regex> 
#include <algorithm> 
#include <iterator> 

using namespace std; 


vector<string> splitter(string in_pattern, string& content){ 
    vector<string> split_content; 

    regex pattern(in_pattern); 
    copy(sregex_token_iterator(content.begin(), content.end(), pattern, -1), 
    sregex_token_iterator(),back_inserter(split_content)); 
    return split_content; 
} 

int main() 
{ 

    string sentence = "This is the first line\n"; 
    sentence += "This is the second line\n"; 
    sentence += "This is the third line\n"; 

    vector<string> lines = splitter(R"(\n)", sentence); 

    for (string line: lines){cout << line << endl;} 

} 

// 1) We have a string with multiple lines 
// 2) we split those into an array (vector) 
// 3) We print out those elements in a for loop 


// My Background. . . 
// github.com/Radicalware 
// Radicalware.net 
// https://www.youtube.com/channel/UCivwmYxoOdDT3GmDnD0CfQA/playlists 
+0

O ile ten fragment kodu może być rozwiązaniem, [w tym wyjaśnienie] (// meta.stackexchange.com/questions/114762/explaining-entirely- code-based-answers) naprawdę pomaga poprawić jakość twojego posta. Pamiętaj, że odpowiadasz na pytanie przeznaczone dla czytelników w przyszłości, a te osoby mogą nie znać powodów sugestii dotyczących kodu. – peacetype

+0

Po przewinięciu zobaczysz komentarze w kodzie. Stack Overflow nie pozwala mi umieścić tekstu poza blokiem kodu z jakiegoś powodu. – Scourge

+0

// 1) Mamy ciąg z wieloma liniami // 2) dzielimy je na tablicę (wektor) // 3) Drukujemy te elementy w pętli for – Scourge