views:

820

answers:

3

Hi,

I have 2 std::string. I just want to, given the input string:

  1. capitalize every letter
  2. assign the capitalized letter to the output string.

How come this works:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), std::back_inserter(out), std::toupper);

but this doesn't (results in a program crash)?

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), out.begin(), std::toupper);

because this works (at least on the same string:

  std::string s="hello";
  std::string out;
  std::transform(s.begin(), s.end(), s.begin(), std::toupper);
A: 

Thats the sense of a backinserter: It inserts elements to a container. using begin(), you pass a iterator to a empty container and modify invalid iterators.

I am sorry - my edits interfered with your comments. I first posted something wrong accidentally.

RED SOFT ADAIR
`std::transform` will apply the function on every character of the string.
Pierre Bourdon
+2  A: 

I'd say that the iterator returned by out.begin() is not valid after a couple of increments for the empty string. After the first ++ it's ==out.end(), then the behavior after the next increment is undefined.

After all this exactly what insert iterator is for.

Michael Krelin - hacker
Wouldn't .begin() equal .end() immediately for an empty string, rather than after the first increment?
Kylotan
Kylotan, I think it would, right.
Michael Krelin - hacker
+14  A: 

There is no space in out. C++ algorithms do not grow their target containers automatically. You must either make the space yourself, or use a inserter adaptor.

To make space in out, do this:

out.resize(s.length());

[edit] Another option is to create the output string with correct size with this constructor.

std::string out(s.length(), 'X');

hrnt
You're right, it should be `resize`, not `reserve`. Upvote for you, then.
PiotrLegnica
+1, but better yet, use `std::string(size_type, char)` constructor to preallocate.
Pavel Minaev
Good comment. I modified my answer accordingly.
hrnt