Reputation: 87
int main()
{
char hmm[1000];
cin.getline(hmm, 1000);
cout << hmm << endl; //this was to test if I could assign my input to the array properly
for (int sayac = 0; hmm[sayac] != '@'; sayac++) {
if (!isdigit(hmm[sayac])) {
if (islower(hmm[sayac]))
cout << toupper(hmm[sayac]);
else if (isupper(hmm[sayac]))
cout << tolower(hmm[sayac]);
else
cout << hmm[sayac];
}
}
"Write a program that reads keyboard input to the @ symbol and that echoes the input except for digits, converting each uppercase character to lowercase, and vice versa. (Don’t forget the cctype family.) "
I'm doing this exercise from the primer book. But when I run it, it returns the ascii order of the char, not the uppercase/lowercase version of the character. Couldn't figure out the problem. Can someone tell my why please?
(I may have other problems about the exercise, please don't correct them if I have. I want to fix it on my own (except the problem I explained), but I can't check the other ones as I have this problem.
Upvotes: 4
Views: 1820
Reputation: 29022
It's a question of representation. There is no difference between a character and that character's numeric value. It's all in how you choose to display it. For example, the character 'a
' is just a constant with a value equal to the character's numeric value.
The problem you are having is that std::toupper
and std::tolower
return an int
rather than a char
. One reason for that is that they handle EOF
values, which are not necessarily representable by char
. As a consequence, std::cout
see you are trying to print an int
and not a char
. The standard behavior for streaming an int
is to print the number. The solution is then to cast your result to char
to force the value to be interpreted as a character. You can use something like std::cout << static_cast<char>(std::toupper(hmm[sayac]));
.
Try the following :
#include <cctype>
#include <iostream>
int main()
{
char hmm[1000];
std::cin.getline(hmm, 1000);
std::cout << hmm << std::endl; //this was to test if I could assign my input to the array properly
for (int sayac = 0; hmm[sayac] != '@'; sayac++) {
if (!std::isdigit(hmm[sayac])) {
if (std::islower(hmm[sayac]))
std::cout << static_cast<char>(std::toupper(hmm[sayac]));
else if (isupper(hmm[sayac]))
std::cout << static_cast<char>(std::tolower(hmm[sayac]));
else
std::cout << hmm[sayac];
}
}
}
You should also consider using an std::string
instead of an array of char
of arbitrary length. Also, take note that you have undefined behavior if the input string does not contain @
.
Upvotes: 2
Reputation: 40100
When writing
std::cout << toupper('a');
the following happen:
int toupper(int ch)
is called, and returns an integer whose value is 'A'
(0x41
).std::basic_ostream::operator<<(std::cout, 0x41)
is called, that is the int
(2) overload since an int
was provided.Overall, it prints "65".
As a solution, you can cast back your upper case to a char
:
std::cout << static_cast<char>(toupper('a'));
Upvotes: 6