1036

I want to convert a std::string to lowercase. I am aware of the function tolower(). However, in the past I have had issues with this function and it is hardly ideal anyway as using it with a std::string would require iterating over each character.

Is there an alternative which works 100% of the time?

14
  • 54
    How else would you convert each element of a list of anything to something else, without iterating through the list? A string is just a list of characters, if you need to apply some function to each character, your going to have to iterate through the string. No way around that. Commented Nov 24, 2008 at 12:14
  • 29
    Why exactly does this question mert down rating? I don't have a problem with iterating through my string, but I am asking if there are other functions apart from tolower(), toupper() etc. Commented Nov 24, 2008 at 12:24
  • 16
    @Dan: If they might already be lowercase, but are definitely A-Z or a-z, you can OR with 0x20 instead of adding. One of those so-smart-it's-probably-dumb optimisations that are almost never worth it... Commented Nov 24, 2008 at 13:11
  • 6
    I don't know why it would've been down-voted... certainly it's worded a little oddly (because you do have to iterate through every item somehow), but it's a valid question Commented Nov 24, 2008 at 13:19
  • 6
    Note: tolower() doesn't work 100% of the time. Lowercase/uppercase operations only apply to characters, and std::string is essentially an array of bytes, not characters. Plain tolower is nice for ASCII string, but it will not lowercase a latin-1 or utf-8 string correctly. You must know string's encoding and probably decode it before you can lowercase its characters. Commented Nov 24, 2008 at 14:42

32 Answers 32

1
2
-1

I wrote a templated version that works with any string :

#include <type_traits> // std::decay #include <ctype.h> // std::toupper & std::tolower template <class T = void> struct farg_t { using type = T; }; template <template<typename ...> class T1, class T2> struct farg_t <T1<T2>> { using type = T2*; }; //--------------- template<class T, class T2 = typename std::decay< typename farg_t<T>::type >::type> void ToUpper(T& str) { T2 t = &str[0]; for (; *t; ++t) *t = std::toupper(*t); } template<class T, class T2 = typename std::decay< typename farg_t<T>::type >::type> void Tolower(T& str) { T2 t = &str[0]; for (; *t; ++t) *t = std::tolower(*t); } 

Tested with gcc compiler:

#include <iostream> #include "upove_code.h" int main() { std::string str1 = "hEllo "; char str2 [] = "wOrld"; ToUpper(str1); ToUpper(str2); std::cout << str1 << str2 << '\n'; Tolower(str1); Tolower(str2); std::cout << str1 << str2 << '\n'; return 0; } 

output:

>HELLO WORLD > >hello world 
Sign up to request clarification or add additional context in comments.

Comments

-3

This could be another simple version to convert uppercase to lowercase and vice versa. I used VS2017 community version to compile this source code.

#include <iostream> #include <string> using namespace std; int main() { std::string _input = "lowercasetouppercase"; #if 0 // My idea is to use the ascii value to convert char upperA = 'A'; char lowerA = 'a'; cout << (int)upperA << endl; // ASCII value of 'A' -> 65 cout << (int)lowerA << endl; // ASCII value of 'a' -> 97 // 97-65 = 32; // Difference of ASCII value of upper and lower a #endif // 0 cout << "Input String = " << _input.c_str() << endl; for (int i = 0; i < _input.length(); ++i) { _input[i] -= 32; // To convert lower to upper #if 0 _input[i] += 32; // To convert upper to lower #endif // 0 } cout << "Output String = " << _input.c_str() << endl; return 0; } 

Note: if there are special characters then need to be handled using condition check.

Comments

1
2

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.