Sign in to follow this  
password

Picking out a part of a std::string

Recommended Posts

password    181
I'm trying to copy a part of a std::string into another string, but I cannot find any function that does what I want in the reference. Example: const int Length = 10; std::string temp = "abc def ghi jkl mno pqr stu vxyz"; std::string message = (temp.end(), temp.end()-Length); I want to pick out the last part of the original string, in this case the last 10 characters.

Share this post


Link to post
Share on other sites
MaulingMonkey    1730
If you want to use iterators:
std::string message( temp.end()-Length, temp.end() );
Notes here: We're using std::string's 2 parameter constructor (which you can't call using assignment construction syntax... hence the lack of an '=' here). Also, standard C++ convention dictates that the beginning iterator is always first -- since temp.end()-Length is before temp.end(), the parameter order needs to be swapped.

If you want to accomplish the same thing with an existing std::string you can use it's assign function (or a temporary):

std::string message;
message.assign( temp.end()-Length, temp.end() ); // with assign
message = std::string( temp.end()-Length, temp.end() ); // with unnamed temporary -- note we have to explicitly name the type here.




As for how your code is being handled: You're using the comma operator, which means your code behaves something like this:
temp.end();
std::string message = temp.end()-Length;

Which is to say, it doesn't compile, since you can't assign a std::string to a single iterator. The comma operator effectively simply evaluates each item in sequence and 'returns' the last one.

Share this post


Link to post
Share on other sites
swiftcoder    18437
Quote:
Original post by MaulingMonkey
As for how your code is being handled: You're using the comma operator, which means your code behaves something like this:
temp.end();
std::string message = temp.end()-Length;

Which is to say, it doesn't compile, since you can't assign a std::string to a single iterator. The comma operator effectively simply evaluates each item in sequence and 'returns' the last one.
As a thought exercise, the comma operator can be overridden to make that syntax work - though I would highly recommend not doing this in real code:
template <typename IterT>
std::string operator , (const IterT &begin, const IterT &end)
{
return std::string(begin, end);
}

Share this post


Link to post
Share on other sites
MaulingMonkey    1730
Quote:
Original post by swiftcoder
Quote:
Original post by MaulingMonkey
As for how your code is being handled: You're using the comma operator, which means your code behaves something like this:
temp.end();
std::string message = temp.end()-Length;

Which is to say, it doesn't compile, since you can't assign a std::string to a single iterator. The comma operator effectively simply evaluates each item in sequence and 'returns' the last one.
As a thought exercise, the comma operator can be overridden to make that syntax work - though I would highly recommend not doing this in real code:
*** Source Snippet Removed ***


If you're going to go and create great evil like that, you might as well go all out with implicit conversions:
template < typename Iterator >
class range {
Iterator begin, end;
public:
range( Iterator begin, Iterator end ): begin(begin), end(end) {}
template < typename Container > operator Container() const { return Container( begin, end ); }
};

template < typename IterT >
range<IterT> operator , (const IterT &begin, const IterT &end)
{
return range<IterT>(begin, end);
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this