C++ teilt Zeichenfolge für Zeile auf

Lesezeit: 4 Minuten

Ich muss Zeile für Zeile aufteilen. Ich habe es früher so gemacht:

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

Ich gebe “wir sind eins.\nja wir sind” ein. und rufen Sie die doSegment-Methode auf. Aber beim Debuggen habe ich festgestellt, dass der Satzparameter “we are one.\\nyes we are” lautet und die Aufteilung fehlgeschlagen ist. Kann mir jemand sagen warum das passiert ist und was ich tun soll. Gibt es sonst noch etwas, mit dem ich Strings in C++ aufteilen kann? Danke !

  • Ich schlage vor, echtes C++ zu verwenden – werfen Sie einen Blick auf std::getline

    – Adrian Kornisch

    1. November 2012 um 6:41 Uhr

  • Sie müssen einige Änderungen an der Eingabe vornehmen. Nicht die Split-Funktion.

    – halb

    1. November 2012 um 6:51 Uhr

  • Sei vorsichtig mit strtok da es die Zeichenfolge ändert, die Sie ihm übergeben.

    – Irgendein Programmierer-Typ

    1. November 2012 um 7:13 Uhr

Benutzer-Avatar
billz

Ich möchte std::getline oder std::string::find verwenden, um die Zeichenfolge zu durchlaufen. Der folgende Code demonstriert die Getline-Funktion

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

  • Noch eine Frage. Ich war mir nicht sicher, ob der Stringstream geschlossen werden muss.

    – Wangzhiju

    1. November 2012 um 8:07 Uhr

  • Es ist eine lokale Variable, die sich selbst zerstört, wenn sie aus doSegment herauskommt.

    – billz

    1. November 2012 um 8:13 Uhr

Benutzer-Avatar
Irgendein Programmierer

Du kannst anrufen std::string::find in einer Schleife und die Verwendung 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;
}

Siehe Beispiel hier.

  • Wenn Sie ein Trennzeichen verwenden, das mehr als ein Zeichen hat, wie ich es bin, sollten Sie das “prev = pos + 1;” ändern. Zeile zu “prev = pos + delimiter.size();” stattdessen. Andernfalls bleiben die restlichen Zeichen am Anfang des nächsten Elements im Vektor übrig.

    – Dennis Munsie

    15. Dezember 2015 um 19:04 Uhr

Benutzer-Avatar
Oleksandr Koslow

#include <sstream>
#include <string>
#include <vector>

std::vector<std::string> split_string_by_newline(const std::string& str)
{
    auto result = std::vector<std::string>{};
    auto ss = std::stringstream{str};

    for (std::string line; std::getline(ss, line, '\n');)
        result.push_back(line);

    return result;
}

  • Dieser Code funktioniert weder mit noch ohne C++ 11. “Fehler: zu viele Initialisierer für ‘std::stringstream’ {alias ‘std::__cxx11::basic_stringstream‘}|”

    – Abstrakter Space Crack

    9. November 2020 um 3:11 Uhr

  • Sie können hier nachsehen godbolt.org/z/3axvrx dass es funktioniert.

    – Oleksandr Koslow

    10. November 2020 um 15:09 Uhr

  • @dan-donnelly, ich hatte auch diesen Fehler. Es stellte sich heraus, dass ich vergessen hatte, einzuschließen.

    – clipitar

    11. November 2021 um 18:06 Uhr


Benutzer-Avatar
Geißel

#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. Wir haben eine Zeichenfolge mit mehreren Zeilen
  2. wir teilen diese in ein Array (Vektor)
  3. Wir geben diese Elemente in einer for-Schleife aus

Diese ziemlich ineffiziente Methode durchläuft die Zeichenfolge einfach, bis sie auf ein Escape-Zeichen für den Zeilenumbruch \n trifft. Dann erstellt es einen Teilstring und fügt ihn einem Vektor hinzu.

std::vector<std::string> Loader::StringToLines(std::string string)
{
    std::vector<std::string> result;
    std::string temp;
    int markbegin = 0;
    int markend = 0;

    for (int i = 0; i < string.length(); ++i) {     
        if (string[i] == '\n') {
            markend = i;
            result.push_back(string.substr(markbegin, markend - markbegin));
            markbegin = (i + 1);
        }
    }
    return result;
}

  • verarbeitet keine nachgestellten Zeilenumbrüche nicht richtig

    – LMD

    10. Januar 2021 um 22:24 Uhr

  • verarbeitet keine nachgestellten Zeilenumbrüche nicht richtig

    – LMD

    10. Januar 2021 um 22:24 Uhr

1015600cookie-checkC++ teilt Zeichenfolge für Zeile auf

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy