1

Can someone explain why this short code in C++ doesn't produce the expected output. The code is supposed to print the string in capital letters.

#include <iostream>
#include <string>
using namespace std;

int main(){
    string sample("hi, i like cats and dogs.");
    cout << "small: " << sample << endl << "BIG  : ";

    for(char c: sample)
        cout << toupper(c);
    cout<<endl;

return 0;
}

The output of the above program is:

small: hi, i like cats and dogs.
BIG  : 72734432733276737569326765848332657868326879718346

but I expected:

small: hi, i like cats and dogs.
BIG  : HI, I LIKE CATS AND DOGS.

I've only programmed in python.

user3697625
  • 167
  • 4
  • 17
  • ... which is one the strangest and more confusing parts of the C++ standard library. The fact that none of your typical char conversion functions do what you'd think they would do in the way that you'd think they would do it. See also isdigit, isspace, ... – Barry Jun 14 '15 at 22:41
  • According to 'C++ Primer 5th Edition': "toupper(c) -->If c is a lowercase letter, returns it's equivalent; otherwise returns c unchanged. " – user3697625 Jun 14 '15 at 22:43

3 Answers3

8

toupper returns int. You need to cast the return value to char such that the output stream operator << prints out the character and not its numeric value.

You should also cast the input to unsigned char, to cover the case where char is signed and your character set includes negative numbers (this would invoke undefined behaviour in toupper). For example,

cout << static_cast<char>(toupper(static_cast<unsigned char>(c)));

Note that you need to include the relevant header (cctype if you want std::toupper or ctype.h if you want C's toupper.)

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 2
    You also want to cast the *input* to `toupper` to `unsigned char` (otherwise, negative values such as most accented characters will give UB). – Jerry Coffin Jun 14 '15 at 22:41
  • 1
    If you use `std::ctype::toupper` then you avoid the casting issues, since it receives and returns an appropriate character type. – rici Jun 14 '15 at 22:57
0

It's printing the ASCII values which are integers. I agree with @Captain Obvlious.

0
#include <iostream>
#include <string>
using namespace std;

int main(){
    string sample("hi, i like cats and dogs.");
    cout << "small: " << sample << endl << "BIG  : ";

    for(char c: sample)
        cout << (char)toupper(c);
    cout<<endl;

return 0;
}

// toupper() return integer value