1

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

5
  • 1
    #include <string>/#include <sstream> ? Commented Aug 29, 2012 at 10:34
  • I don't think I understand the logic of your sort_function. What is it supposed to do with that stringstream? Commented Aug 29, 2012 at 10:34
  • @ForEver both of them are included Commented Aug 29, 2012 at 10:38
  • @MihaiTodor: The stringstream is extracting the second word from each string, so these can be compared. Commented Aug 29, 2012 at 10:41
  • @MikeSeymour Hm... I had no idea it can tokenize strings based on spaces. Nice functionality. Is there any way to change the token? Commented Aug 29, 2012 at 10:44

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.