Fractionner une string en C++ à l'aide d'un délimiteur
Cet article explique comment diviser une chaîne en C++ à l'aide d'un délimiteur et construire un vector de strings contenant des strings individuelles.
La bibliothèque standard C++ ne fournissait aucune fonction intégrée pour cette tâche concrète. Cet article donne un aperçu de certaines des alternatives disponibles pour y parvenir.
1. Utilisation find_first_not_of()
avec find()
fonction
Nous pouvons utiliser une combinaison de strings find_first_not_of() et find() pour diviser une string en C++, comme indiqué ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <iostream> #include <string> #include <vector> void tokenize(std::string const &str, const char delim, std::vector<std::string> &out) { size_t start; size_t end = 0; while ((start = str.find_first_not_of(delim, end)) != std::string::npos) { end = str.find(delim, start); out.push_back(str.substr(start, end - start)); } } int main() { std::string s = "C*C++*Java"; const char delim = '*'; std::vector<std::string> out; tokenize(s, delim, out); for (auto &s: out) { std::cout << s << std::endl; } return 0; } |
Résultat:
C
C++
Java
2. Utilisation getline()
fonction
Une autre bonne alternative est d'utiliser le std::getline fonction, qui extrait les caractères de la istream
objet et les stocke dans un flux spécifié jusqu'à ce que le caractère de délimitation soit trouvé.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include <iostream> #include <string> #include <vector> #include <sstream> void tokenize(std::string const &str, const char delim, std::vector<std::string> &out) { // construit un flux à partir de la string std::stringstream ss(str); std::string s; while (std::getline(ss, s, delim)) { out.push_back(s); } } int main() { std::string s = "C*C++*Java"; const char delim = '*'; std::vector<std::string> out; tokenize(s, delim, out); for (auto &s: out) { std::cout << s << std::endl; } return 0; } |
Résultat:
C
C++
Java
3. Utilisation std::regex_token_iterator
fonction
Une autre solution consiste à utiliser le std::sregex_token_iterator qui est une spécialisation de std::regex_token_iterator<std::string::const_iterator>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <iostream> #include <regex> #include <string> int main() { std::string s = "C*C++*Java"; std::regex regex("\\*"); std::vector<std::string> out( std::sregex_token_iterator(s.begin(), s.end(), regex, -1), std::sregex_token_iterator() ); for (auto &s: out) { std::cout << s << std::endl; } return 0; } |
Résultat:
C
C++
Java
4. Utilisez std::strtok
fonction
Nous pouvons également utiliser le strtok() fonction pour diviser une string en jetons, comme indiqué ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#include <iostream> #include <string> #include <vector> #include <cstring> void tokenize(std::string const &str, const char* delim, std::vector<std::string> &out) { char *token = strtok(const_cast<char*>(str.c_str()), delim); while (token != nullptr) { out.push_back(std::string(token)); token = strtok(nullptr, delim); } } int main() { std::string s = "C*C++*Java"; const char* delim = "*"; std::vector<std::string> out; tokenize(s, delim, out); for (auto &s: out) { std::cout << s << std::endl; } return 0; } |
Résultat:
C
C++
Java
5. Utilisation std::string::find
fonction
Enfin, nous pouvons utiliser std::string::find
algorithme avec std::string::substr
qui est démontré ci-dessous :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include <iostream> #include <string> #include <vector> #include <algorithm> void tokenize(const std::string &s, const char delim, std::vector<std::string> &out) { std::string::size_type beg = 0; for (auto end = 0; (end = s.find(delim, end)) != std::string::npos; ++end) { out.push_back(s.substr(beg, end - beg)); beg = end + 1; } out.push_back(s.substr(beg)); } int main() { std::string s = "C*C++*Java"; const char delim = '*'; std::vector<std::string> out; tokenize(s, delim, out); for (auto &s: out) { std::cout << s << std::endl; } return 0; } |
Résultat:
C
C++
Java
Il s'agit de diviser une string en C++ à l'aide d'un délimiteur.