Pour ceux qui n'aiment pas sacrifier l'efficacité au profit de la taille du code et qui considèrent l'efficacité comme une forme d'élégance, ce qui suit devrait faire l'affaire (et je pense que la classe de conteneurs de modèles est un ajout extrêmement élégant) :
template < class ContainerT >
void tokenize(const std::string& str, ContainerT& tokens,
const std::string& delimiters = " ", bool trimEmpty = false)
{
std::string::size_type pos, lastPos = 0, length = str.length();
using value_type = typename ContainerT::value_type;
using size_type = typename ContainerT::size_type;
while(lastPos < length + 1)
{
pos = str.find_first_of(delimiters, lastPos);
if(pos == std::string::npos)
{
pos = length;
}
if(pos != lastPos || !trimEmpty)
tokens.push_back(value_type(str.data()+lastPos,
(size_type)pos-lastPos ));
lastPos = pos + 1;
}
}
Je choisis généralement d'utiliser std::vector<std::string>
comme deuxième paramètre ( ContainerT
)... mais list<>
est bien plus rapide que vector<>
pour les cas où l'accès direct n'est pas nécessaire, et vous pouvez même créer votre propre classe de chaîne et utiliser quelque chose comme std::list<subString>
où subString
ne fait pas de copies pour des augmentations de vitesse incroyables.
Il est plus de deux fois plus rapide que le tokenize le plus rapide de cette page et presque 5 fois plus rapide que certains autres. De plus, avec les types de paramètres parfaits, vous pouvez éliminer toutes les copies de chaînes et de listes pour augmenter encore la vitesse.
De plus, il ne renvoie pas le résultat (extrêmement inefficace), mais transmet plutôt les jetons comme une référence, ce qui vous permet également d'accumuler des jetons en utilisant plusieurs appels si vous le souhaitez.
Enfin, il vous permet de spécifier s'il faut couper les tokens vides des résultats via un dernier paramètre facultatif.
Tout ce dont il a besoin est std::string
... le reste est optionnel. Il n'utilise pas les flux ou la bibliothèque boost, mais est suffisamment flexible pour pouvoir accepter certains de ces types étrangers naturellement.
692 votes
Mec... L'élégance est juste une façon élégante de dire "l'efficacité qui est jolie" dans mon livre. N'hésitez pas à utiliser les fonctions C et les méthodes rapides pour accomplir quelque chose simplement parce que ce n'est pas contenu dans un modèle ;)
19 votes
while (iss) { string subs; iss >> subs; cout << "Substring: " << sub << endl; }
0 votes
@nlaq, Sauf que vous devriez convertir votre objet chaîne de caractères en utilisant c_str(), et revenir à une chaîne de caractères si vous avez toujours besoin que ce soit une chaîne de caractères, non ?
28 votes
@Eduardo : c'est faux aussi... vous devez tester l'iss entre la tentative de streamer une autre valeur et l'utilisation de cette valeur, c'est à dire
string sub; while (iss >> sub) cout << "Substring: " << sub << '\n';
1 votes
Que diriez-vous d'un tokenizer de chaîne de caractères : cplusplus.com/reference/cstring/strtok
14 votes
Diverses options en C++ pour faire cela par défaut : cplusplus.com/faq/sequences/strings/split
27 votes
L'élégance, c'est plus que de l'efficacité. Les attributs de l'élégance comprennent un faible nombre de lignes et une grande lisibilité. À mon avis, l'élégance n'est pas un substitut de l'efficacité mais de la maintenabilité.
4 votes
La plupart des réponses ici sont notamment latinocentriques. De nombreuses réponses supposent qu'un seul caractère peut être utilisé comme "espace", même si la question définit le délimiteur comme un espace. L'Unicode compte au moins 25 caractères d'espacement. Mais la délimitation des mots n'est pas seulement une question d'espace. Par exemple, dans une écriture syllabique, comme le tibétain, la délimitation des mots est un problème sémantique plutôt que syntaxique. Par conséquent, l'utilisation des espaces blancs pour extraire les mots n'est pas une approche appropriée pour de nombreuses langues.
0 votes
Petit complément à ce qui précède. Vous pouvez ajouter une facette locale qui traite la ponctuation comme un espace afin de ne pas avoir à la gérer séparément. codereview.stackexchange.com/a/57467/507
1 votes
Votre code original est plus élégant que les réponses.