2010-04-28 7 views
3

J'essaie de diviser une chaîne en utilisant des espaces comme délimiteur. Je voudrais stocker chaque jeton dans un tableau ou un vecteur.Chaîne fractionnée C++

J'ai essayé.

string tempInput; 
    cin >> tempInput; 
    string input[5]; 

    stringstream ss(tempInput); // Insert the string into a stream 
    int i=0; 
    while (ss >> tempInput){ 
     input[i] = tempInput; 
     i++; 
    } 

Le problème est que si je entrée « ceci est un test », le tableau semble que pour stocker l'entrée [0] = « this ». Il ne contient pas de valeurs pour l'entrée [2] à l'entrée [4].

J'ai aussi essayé d'utiliser un vecteur mais avec le même résultat.

+0

pas vraiment dupe. C'est "Où ai-je fait une erreur" vs "Quelle est la meilleure façon de ..."? –

+0

Alors que la question est exactement la même: comment diviser une chaîne, je crois que la question référée par @pmr traite du problème générique, alors que dans cette question, le problème n'est pas dans la division réelle –

+0

@David @SF Oui, vous ont raison. Malheureusement, la plupart des réponses ne traitent pas la question de cette façon. – pmr

Répondre

5

Accédez aux questions en double pour apprendre à diviser une chaîne en mots, mais votre méthode est correcte. Le problème réel réside dans la façon dont vous lisez l'entrée avant essayer de le diviser:

string tempInput; 
cin >> tempInput; // !!! 

Lorsque vous utilisez le cin >> tempInput, vous obtenez seulement le premier mot de l'entrée, et non pas tout le texte. Il y a deux façons de travailler votre chemin de ce qui la plus simple est Oubliant sur le stringstream et itérez directement sur l'entrée:

std::string tempInput; 
std::vector<std::string> tokens; 
while (std::cin >> tempInput) { 
    tokens.push_back(tempInput); 
} 
// alternatively, including algorithm and iterator headers: 
std::vector<std::string> tokens; 
std::copy(std::istream_iterator<std::string>(std::cin), 
      std::istream_iterator<std::string>(), 
      std::back_inserter(tokens)); 

Cette approche vous donnera tous les jetons dans l'entrée dans un seul vecteur . Si vous avez besoin de travailler avec chaque ligne separatedly vous devez utiliser getline de l'en-tête <string> au lieu du cin >> tempInput:

std::string tempInput; 
while (getline(std::cin, tempInput)) { // read line 
    // tokenize the line, possibly with your own code or 
    // any answer in the 'duplicate' question 
} 
3

Notez qu'il est beaucoup plus facile à utiliser juste copy:

vector<string> tokens; 
copy(istream_iterator<string>(cin), 
    istream_iterator<string>(), 
    back_inserter(tokens)); 

Quant à savoir pourquoi votre code ne fonctionne pas: vous réutilisez tempInput. Ne fais pas ça. En outre, vous lisez d'abord un seul mot de cin, pas toute la chaîne. C'est pourquoi un seul mot est mis dans le stringstream.

1

La façon la plus simple: Boost.Tokenizer

std::vector<std::string> tokens; 

std::string s = "This is, a test"; 
boost::tokenizer<> tok(s); 
for(boost::tokenizer<>::iterator it=tok.begin(); it != tok.end(); ++it) 
{ 
    tokens.push_back(*it); 
} 

// tokens is ["This", "is", "a", "test"] 

Vous pouvez paramétrer les délimiteurs et les séquences d'échappement pour ne prendre que des espaces si vous le souhaitez, par défaut, il tokenize sur les deux espaces et la ponctuation.

+2

Je souhaite que les gens cessent immédiatement d'augmenter Boost comme solution. De nombreux endroits, y compris où je suis actuellement (et travaillé précédemment) doivent passer des mois à examiner les licences et audit de tout projet open source avant de pouvoir l'utiliser et ne valent généralement pas la peine et l'effort avant d'obtenir un lumière verte (ou rouge). Aussi, si c'est une question de devoirs alors le tuteur ne serait pas impressionné si l'étudiant a remis le code criblé Boost. –

+3

@ graham.reeds: désolé d'entendre cela mais - bien que la chance. Boost est une - et très souvent ** la solution la plus appropriée. Êtes-vous autorisé à utiliser la bibliothèque standard?Après tout, c'est un standard ouvert et ses implémentations sont généralement open source. En tout cas, blâmer votre entreprise, pas Boost ou des réponses utiles. :-( –

+2

@ graham.reeds: et l'alternative est de cacher des réponses parfaitement valides qui peuvent être utilisées dans d'autres environnements? Et si quelqu'un demande comment analyser un XML en C++? Souhaitez-vous fournir l'implémentation d'un analyseur XML? Dans des cas aussi simples, la question obtiendra probablement à la fois des solutions purement C++ et basées sur des bibliothèques et cela, je crois, ajoute de la valeur plutôt que de l'enlever (Note: je n'ai pas mis puisque je crois que le vrai problème rencontré par @Mike n'est pas tokenizing la chaîne mais plutôt comment il lit l'entrée) –

Questions connexes