How could one convert a string to upper case. The examples I have found from googling only have to deal with chars.
The faster one if you use only ASCII characters:
for(i=0;str[i]!=0;i++)
if(str[i]<='z' && str[i]>='a')
str[i]+='A'-'a';
Please note that this code run faster but only works on ASCII and is not an "abstract" solution.
Extended version for other UTF8 alphabets:
...
if(str[i]<='z' && str[i]>='a') //is latin
str[i]+='A'-'a';
else if(str[i]<='я' && str[i]>='а') //cyrillic
str[i]+='Я'-'я'
else if(str[i]<='ω' && str[i]>='α') //greek
str[i]+='Ω'-'ω'
//etc...
If you need full UNICODE solutions or more conventional and abstract solutions, go for other answers and work with methods of C++ strings.
Use a lambda.
std::string s("change my case");
std::locale locale;
auto to_upper = [&locale] (char ch) { return std::use_facet<std::ctype<char>>(locale).toupper(ch); };
std::transform(s.begin(), s.end(), s.begin(), to_upper);
#include <string>
#include <locale>
std::string str = "Hello World!";
auto & f = std::use_facet<std::ctype<char>>(std::locale());
f.toupper(str.data(), str.data() + str.size());
This will perform better than all the answers that use the global toupper function, and is presumably what boost::to_upper is doing underneath.
This is because ::toupper has to look up the locale - because it might've been changed by a different thread - for every invocation, whereas here only the call to locale() has this penalty. And looking up the locale generally involves taking a lock.
This also works with C++98 after you replace the auto, use of the new non-const str.data(), and add a space to break the template closing (">>" to "> >") like this:
std::use_facet<std::ctype<char> > & f =
std::use_facet<std::ctype<char> >(std::locale());
f.toupper(const_cast<char *>(str.data()), str.data() + str.size());
std::string str = "STriNg oF mIxID CasE lETteRS"
C++ 11
Using for_each
std::for_each(str.begin(), str.end(), [](char & c){ c = ::toupper(c); });
Using transform
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
C++ (Winodws Only)
_strupr_s(str, str.length());
C++ (Using Boost Library)
boost::to_upper_copy(str)
I use this solution. I know you're not supposed to modify that data area.... but I think that's mostly for buffer overrun bugs and null character.... upper casing things isn't the same.
void to_upper(const std::string str) {
std::string::iterator it;
int i;
for ( i=0;i<str.size();++i ) {
((char *)(void *)str.data())[i]=toupper(((char *)str.data())[i]);
}
}
The answer of @dirkgently is very inspiring, but I want to emphasize that due to the concern as is shown below,
Like all other functions from , the behavior of std::toupper is undefined if the argument's value is neither representable as unsigned char nor equal to EOF. To use these functions safely with plain chars (or signed chars), the argument should first be converted to unsigned char
Reference: std::toupper
the correct usage of std::toupper
should be:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <string>
void ToUpper(std::string& input)
{
std::for_each(std::begin(input), std::end(input), [](char& c) {
c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
});
}
int main()
{
std::string s{ "Hello world!" };
std::cout << s << std::endl;
::ToUpper(s);
std::cout << s << std::endl;
return 0;
}
Output:
Hello world!
HELLO WORLD!