Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does s[i]^=32 convert upper to lower case?

int main()
{
    string s;
    cout << "enter the string :" << endl;
    cin >> s;
    for (int i = 0; i < s.length(); i++)
        s[i] ^= 32;
    cout << "modified string is : " << s << endl;
    return 0;
}

I saw this code which converts uppercase to lowercase on stackoverflow.

But I don't understand the line s[i] = s[i]^32.

How does it work?

like image 391
Rashed Sami Avatar asked Nov 16 '16 20:11

Rashed Sami


People also ask

How do you convert a whole string to lowercase?

Converting an input character to Lowercase We need to add 32 to the ASCII value of the input character to convert it to lowercase.

How do I change lowercase to uppercase in CPP?

If lowercase, convert it to uppercase using toupper() function, if uppercase, convert it to lowercase using tolower() function.

How do you lowercase a letter in C++?

The tolower() function in C++ converts a given character to lowercase.


2 Answers

^= is the exclusive-or assignment operator. 32 is 100000 in binary, so ^= 32 switches the fifth bit in the destination. In ASCII, lower and upper case letters are 32 positions apart, so this converts lower to upper case, and also the other way.

But it only works for ASCII, not for Unicode for example, and only for letters. To write portable C++, you should not assume the character encoding to be ASCII, so please don't use such code. @πάντα ῥεῖs answer shows a way to do it properly.

like image 176
alain Avatar answered Oct 13 '22 13:10

alain


How does it work?

Let's see for ASCII value 'A':

'A' is binary 1000001

XORed with 32 (binary 100000)

yields any value where the upper character indicating bit isn't set:

1000001 XOR 100000 = 1100001 == 'a' in ASCII.


Any sane and portable c or c++ application should use tolower():

int main()
{
    string s;
    cout<<"enter the string :"<<endl;
    cin>>s;
    for (int i=0;i<s.length();i++) s[i] = tolower( (unsigned char)s[i] );
                                     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    cout<<"modified string is : "<<s<<endl;
    return 0;
}

The s[i]=s[i]^32 (cargo cult) magic, relies on ASCII table specific mapping to numeric char values.

There are other char code tables like e.g. EBCDIC , where the

 s[i]=s[i]^32

method miserably fails to retrieve the corresponding lower case letters.


There's a more sophisticated c++ version of converting to lower case characters shown in the reference documentation page of std::ctype::tolower().

like image 35
πάντα ῥεῖ Avatar answered Oct 13 '22 15:10

πάντα ῥεῖ