2010-10-06 4 views
2

J'ai une séquence (ou une phrase) et je veux extraire les 2 dernières chaînes.extraire les 2 derniers mots d'une séquence de chaînes, séparés par des espaces

Par exemple,

  • sdfsdfds sdfs dfsd fgsd 3 dsfds devrait produire: 3 dsfds
  • sdfsd (dfgdg)gfdg fg 6 gg devrait produire: 6 gg
+0

Voir aussi cette question: http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c. En outre, cela a peu à voir avec la STL (qui est la partie de la bibliothèque std traitant des conteneurs, des itérateurs et des algorithmes), donc j'ai changé les tags. – sbi

+0

@sbi: std :: string et ses méthodes find (rfind est utile dans ce cas) font partie de STL. Donc je préférerais ne pas enlever le tag STL. –

+0

@Vlad: "The STL" est un nom familier pour les parties de la lib std, qui proviennent de la STL d'origine. [Ce n'est pas un synonyme de la bibliothèque standard.] (Http://en.wikipedia.org/wiki/Standard_Template_Library) On pourrait se demander si 'std :: string' (même pas mentionné dans la question), qui était dans le projet de norme pendant une longue période lorsque le STL est venu et a été seulement plus tard "STLified", appartient à la STL. Ce ne sont pas des myriades de fonctions membres. (Le fait que les algorithmes soient séparés des conteneurs est ce qui distingue le STL, après tout.) Je ne me battrai pas sur cette étiquette, mais c'est faux. – sbi

Répondre

4

Vous pouvez utiliser la fonction std::string::find_last_of pour trouver des espaces.

int main() 
{ 
    std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds"; 

    size_t found1 = test.find_last_of(" "); 
    if (found1 != string::npos) { 
     size_t found2 = test.find_last_of(" ", found1-1); 
     if (found2 != string::npos) 
      std::cout << test.substr(found2+1, found1-found2-1) << std::endl; 
     std::cout << test.substr(found1+1) << std::endl; 
    } 

    return 0; 
} 
2

Ce qui suit fonctionnera que si vos cordes sont séparées par des espaces.

#include <iostream> 
#include <string> 
#include <sstream> 
#include <vector> 
using namespace std; 

int main() 
{ 
    string str = "jfdf fhfeif shfowejef dhfojfe"; 
    stringstream sstr(str); 
    vector<string> vstr; 

    while(sstr >> str) 
    { 
     vstr.push_back(str); 
    } 

    if (vstr.size() >= 2) 
     cout << vstr[vstr.size()-2] << ' '; 
    if (vstr.size()) 
     cout << vstr[vstr.size()-1] << endl; 

    return 0; 
} 
+0

vous voudrez peut-être vérifier que la taille du vecteur est> 2 avant d'y accéder. – sbi

+0

oui, merci. J'ai supposé qu'il y aura assez de chaînes pour l'extraction. – Donotalo

+0

@Donato: (Vous devez répondre correctement aux réponses @ pour qu'elles apparaissent dans l'onglet des réponses des autres personnes. – sbi

1

Renvoie les chaînes dans le mauvais ordre, mais si cela n'a pas d'importance,

std::string s ("some words here"); 

std::string::size_type j; 
for(int i=0; i<2; ++i) { 
    if((j = s.find_last_of(' ')) == std::string::npos) { 
     // there aren't two strings, throw, return, or do something else 
     return 0; 
    } 
    std::cout << s.c_str()+j+1; 
    s = " " + s.substr(0,j); 
} 

Alternativement,

struct extract_two_words { 
    friend std::istream& operator>> (std::istream& in , extract_two_words& etw); 
    std::string word1; 
    std::string word2; 
}; 

std::istream& operator>> (std::istream& in , extract_two_words& etw) { 
    std::string str1, str2; 
    while(in) { 
     in >> str1; 
     in >> str2; 
    } 
    etw.word2 = str1; 
    etw.word1 = str2; 
} 
1

Je vous encourage à jeter un oeil à la Boost bibliothèque. Il a des algorithmes et des structures de données qui vous aident énormément. Voici comment résoudre votre problème en utilisant Boost.StringAlgo:

#include <boost/algorithm/string/split.hpp> 
#include <iostream> 
#include <vector> 
#include <string> 

int main() 
{ 
    std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds"; 

    std::vector<std::string> v; 
    boost::algorithm::split(v, test, [](char c) { return c==' ';}); 
    std::cout << "Second to last: " << v.at(v.size()-2) << std::endl; 
    std::cout << "Last:   " << v.at(v.size()-1) << std::endl; 
} 

Je voudrais aussi vous encourager à toujours utiliser le vecteur :: à la méthode au lieu de []. Cela vous donnera une bonne gestion des erreurs.

1
int main() 
{ 
    std::string test = "sdfsdfds sdfs dfsd fgsd 3 dsfds"; 
    size_t pos = test.length(); 
    for (int i=0; i < 2; i++) 
     pos = test.find_last_of(" ", pos-1); 
    std::cout << test.substr(pos+1) << std::endl; 
} 

:)

Simpler
Questions connexes