Stefan Rogin
Stefan Rogin

Reputation: 1527

Transforming a string to lowercase in a new string

Converting a string can be done with

std::transform(s.begin(), s.end(), s.begin(), ::toupper);

but what's the best way to transform it into a new modified copy ?

tried :

string s1="text",s2;
std::transform(s1.begin(), s1.end(), s2.begin(), ::toupper);

but it fails at runtime with "Segmentation fault"

I managed to do it by :

string s1="text",s2;
s2 = s1;
std::transform(s2.begin(), s2.end(), s2.begin(), ::toupper);

and of course you can create a function to go char by char, but I don't think that's optimal, and I'm not learning anything from this...

Upvotes: 2

Views: 1385

Answers (3)

aafulei
aafulei

Reputation: 2205

I do not quite understand why one of the answers says

// DO NOT use this
std::transform(s1.begin(), s1.end(), std::back_inserter(s2), ::toupper);
//                                   ^^^^^^^^^^^^^^^^^^^^^^

push_back() is a method of std::string and it is perfectly fine to use std::transform with std::back_inserter

#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <string>

int main() {
  std::string s1 = "ABCDEFG";
  std::string s2;
  std::transform(s1.begin(), s1.end(), std::back_inserter(s2),
                 [](unsigned char uc) { return std::tolower(uc); });
  std::cout << s2 << std::endl; // abcdefg
  return 0;
}

Upvotes: 0

R Sahu
R Sahu

Reputation: 206577

Unless use of std::transform is a requirement, you can use:

string s1="text";
string s2 = s1;
for ( auto& ch : s2 )
   ch = toupper((unsigned char)ch);

Upvotes: 1

Columbo
Columbo

Reputation: 60979

std::transform doesn't know containers and will not insert new elements for you.
std::back_inserter provides an iterator that push_backs assigned values:

// DO NOT use this
std::transform(s1.begin(), s1.end(), std::back_inserter(s2), ::toupper);
//                                   ^^^^^^^^^^^^^^^^^^^^^^

However, you should not use the global version of toupper since it's deprecated.
Also you have to cast the argument to unsigned char first, or undefined behavior is easily encountered.

transform does not seem to fit here as you would need a lambda; use

for (auto ch : s1)
    s2 += std::toupper((unsigned char)ch);

Demo.

Upvotes: 6

Related Questions