Reputation: 1527
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
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
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
Reputation: 60979
std::transform
doesn't know containers and will not insert new elements for you. std::back_inserter
provides an iterator that push_back
s 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