81 votes

Diviser une chaîne en utilisant C++11

Quelle serait la méthode la plus simple pour diviser une chaîne en utilisant c++11 ?

J'ai vu la méthode utilisée par ce post , mais je pense qu'il devrait y avoir une façon moins verbeuse de le faire en utilisant la nouvelle norme.

Edit : j'aimerais avoir un vector<string> comme résultat et pouvoir délimiter sur un seul caractère.

67voto

JohannesD Points 4935

std::regex_token_iterator effectue une tokenisation générique basée sur une expression régulière. Cela peut ou non être exagéré pour faire un simple fractionnement sur un seul caractère, mais cela fonctionne et n'est pas trop verbeux :

 std::vector<std::string> split(const string& input, const string& regex) {
    // passing -1 as the submatch index parameter performs splitting
    std::regex re(regex);
    std::sregex_token_iterator
        first{input.begin(), input.end(), re, -1},
        last;
    return {first, last};
}

39voto

bingshen Points 46

Voici un moyen (peut-être moins détaillé) de diviser la chaîne (basé sur le message que vous avez mentionné).

 #include <string>
#include <sstream>
#include <vector>
std::vector<std::string> split(const std::string &s, char delim) {
  std::stringstream ss(s);
  std::string item;
  std::vector<std::string> elems;
  while (std::getline(ss, item, delim)) {
    elems.push_back(item);
    // elems.push_back(std::move(item)); // if C++11 (based on comment from @mchiasson)
  }
  return elems;
}

20voto

fduff Points 1149

Voici un exemple de division d'une chaîne et de remplissage d'un vecteur avec les éléments extraits à l'aide de boost .

 #include <boost/algorithm/string.hpp>

std::string my_input("A,B,EE");
std::vector<std::string> results;

boost::algorithm::split(results, my_input, boost::is_any_of(","));

assert(results[0] == "A");
assert(results[1] == "B");
assert(results[2] == "EE");

17voto

wally Points 6590

Une autre solution regex inspirée d'autres réponses mais, espérons-le, plus courte et plus facile à lire :

 std::string s{"String to split here, and here, and here,..."};
std::regex regex{R"([\s,]+)"}; // split on space and comma
std::sregex_token_iterator it{s.begin(), s.end(), regex, -1};
std::vector<std::string> words{it, {}};

6voto

Faisal Vali Points 10048

Je ne sais pas si c'est moins verbeux, mais il pourrait être plus facile de grok pour ceux qui sont plus aguerris dans les langages dynamiques tels que le javascript. La seule fonctionnalité C++11 qu'il utilise est lambdas.

 #include <string>
#include <cctype>
#include <iostream>
#include <vector>

using namespace std;

int main()
{
  string s = "hello  how    are you won't you tell me your name";
  vector<string> tokens;
  string token;

  for (const auto& c: s) {
    if (!isspace(c))
      token += c;
    else {
      if (token.length()) tokens.push_back(token);
      token.clear();
    }
  }

  if (token.length()) tokens.push_back(token);
     
  return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X