barp
barp

Reputation: 6959

sorting vector of strings in c++ according to index in the string

Hi I have vector of strings,that is the structure of vector : The name of vector is vector

"key:  abc 165.123.34.12", 
"key:  bca 1.1.1.1", 
"key1: bac 3.3.3.3"

I want to sort the vector according to the second field(abc,bac,bac)

My code is;

 bool sort_function(string& str1,string& str2) {

     string nick1,nick2,nick1_ignore,nick2_ignore;

     stringstream ss1(str1) 

     ss1>> nick1_ignore >> nick1;

     stringstream ss2(str2) 

     ss2>> nick2_ignore >> nick2;

     return (nick1<nick2);

 }


     sort(vector.begin(), vector.end(),sort_function);

But it gives a long error starting with error,

  error: no match for ‘operator>>’ in ‘std::basic_stringstream<char>

UPDATE:Error is tl_algo.h: In function ‘_RandomAccessIterator std:..

UPDATE:It is fixed. the error is in function declaration I have to use const string

Upvotes: 1

Views: 379

Answers (2)

James Kanze
James Kanze

Reputation: 154047

I wouldn't use std::istringstream for this sort of thing. If the lines really have the format you describe, something along the lines of:

class CompareFields
{
    int myStart;
    int myEnd;
public:
    CompareFields( int start, int end )
        : myStart( start )
        , myEnd( end )
    {
    }
    bool operator()( std::string const& lhs, std::string const& rhs ) const
    {
        assert( lhs.size() >= myEnd && rhs.size() >= myEnd );
        return std::lexicographical_compare( lhs.begin() + myStart,
                                             lhs.begin() + myEnd,
                                             rhs.begin() + myStart,
                                             rhs.begin() + myEnd );
    }
};

should be all that's needed:

std::sort( v.begin(), v.end(), CompareFields( 6, 9 ) );

If you want to define the fields differently; e.g. as white space, you'll need to redefine CompareFields so that it does the right thing.

Upvotes: 0

ecatmur
ecatmur

Reputation: 157504

The function template overload operator>>(std::basic_istream &, std::string &) is non-const on its istream parameter, so you can't call it on a temporary.

This is confusing, because you can call the member operator>> when reading a primitive e.g. int.

Instead, you'll have to write

stringstream ss1(str1); ss1 >> nick1_ignore >> nick1;

You could also work around this by first reading a no-op manipulator or calling a no-op method to get an lvalue reference:

stringstream(str1).ignore(0) >> nick1_ignore >> nick1;

C++11 fixes this by providing overloads of the free operator>> with the istream parameter an rvalue reference.

Upvotes: 6

Related Questions