web-dev-qa-db-fra.com

Chaîne de partage C ++ par ligne

J'ai besoin de diviser la chaîne par ligne. Je faisais de la manière suivante:

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

J'entre "nous sommes un.\Noui nous le sommes." et appelez la méthode doSegment. Mais quand je débogue, j'ai trouvé que le paramètre de phrase est "nous sommes un. \\ nyes nous sommes", et la division a échoué. Quelqu'un peut-il me dire pourquoi cela s'est produit et que dois-je faire. Y a-t-il de toute façon que je peux utiliser pour diviser la chaîne en C++. Merci !

30
wangzhiju

Je voudrais utiliser std :: getline ou std :: string :: find pour parcourir la chaîne. le code ci-dessous illustre la fonction 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;
}
50
billz

Tu peux appeler std::string::find dans une boucle et l'utilisation 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;
}

Voir l'exemple ici .

15
#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  
1
Scourge

Cette manière assez inefficace parcourt simplement la chaîne jusqu'à ce qu'elle rencontre un\n caractère d'échappement de nouvelle ligne. Il crée ensuite une sous-chaîne et l'ajoute à un vecteur.

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;
}
0
Jelle Bleeker