views:

128

answers:

5

I have any sequence (or sentence) and i want to extract the last 2 strings.

For example,

  • sdfsdfds sdfs dfsd fgsd 3 dsfds should produce: 3 dsfds
  • sdfsd (dfgdg)gfdg fg 6 gg should produce: 6 gg
+1  A: 

The following will work if your strings are whitespace separated.

#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;
}
Donotalo
you might want to check for the vector's size being > 2 before accessing it.
sbi
yep, thanks. i assumed that there will be enough strings for extraction.
Donotalo
@Donato: (You need to properly @address comment replies for them to show up in other people's responses tab. I only came by here by accident.) Up-voted now.
sbi
@sbi, didn't know about this feature. thanks. i thought it is automatic.
Donotalo
+2  A: 

You can use std::string::find_last_of function to find spaces.

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;
}
Kirill V. Lyadvinsky
A: 

Returns the strings in the wrong order, but if that doesn't matter,

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); 
}  

Alternatively,

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;
}
tjm
A: 

I would encourage you to have a look at the Boost library. It has algorithms and data structures that help you tremendously. Here's how to solve your problem using 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;
}

I would also encourage you to always use the vector::at method instead of []. This will give you proper error handling.

Daniel Lidström
A: 
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 :)

dr.manhattan