C ++ std :: transform () and toupper () .. why doesn't this work?

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

  • use every letter
  • capitalize the output string.

How it works:

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

but it is not (leads to a program crash)?

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

because it works (at least on the same line:

  std::string s="hello"; std::string out; std::transform(s.begin(), s.end(), s.begin(), std::toupper); 
+27
c ++ string stl transform
Sep 28 '09 at 20:53
source share
3 answers

There is no space in out . C ++ algorithms do not automatically generate target containers. You must either make the space yourself or use the insert adapter.

To make a space in out , do the following:

out.resize(s.length());

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

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

+38
Sep 28 '09 at 20:57
source share
— -

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

After all, this is exactly what the iterator inserts for.

+2
Sep 28 '09 at 20:57
source share

This means that it supports: it inserts elements into the container. using begin (), you pass the iterator to an empty container and modify the invalid iterators.

Sorry, my changes affected your comments. I first sent something wrong by accident.

0
Sep 28 '09 at 20:56
source share



All Articles