cin >> answer[max];
will read exactly one character because answer[max]
is exactly one character, the character in the array at position max
.
max
is 0 because you have to do things in order. For example,
int max = strlen(answer);
will provide the length of answer
at that time this line is reached. Since the string was initialized one line earlier
char answer[255] = "";
and contains an empty string, max
will be 0. This means answer[max]
is answer[0]
Nothing in the code ever changes max
, so it will remain 0.
OK, say we change things a little and rather than reading into a single character, we read into answer
as a string. You will need to
cin.getline(answer, sizeof(answer));
because
cin >> answer;
will read one whitespace-delimited token. One word. Your stated goal is to read more than one word. istream::getline
will read everything it finds into the first parameter up to the end of the line or it finds the number of characters specified in the second parameter minus 1 (in order to reserve space for the string's null terminator). sizeof(answer)
is literally the size of the answer
array in bytes. We're operating in byte-sized characters so the count of characters and number of bytes are the same. Extra care must be taken if multibyte characters are being used.
This seems like a good place to recommend using std::string
and std::getline
instead. They make a large number of problems, such as the maximum number of characters that can be read, vanish for the vast majority of cases.
I'm not going to use them here, though because the assignment likely has a "No string
s" policy.
So now that we have cin.getline(answer, sizeof(answer));
reading the user's input we can work on getting the size for max
. We could strlen
, but we could also use istream::gcount
to get the number of characters read by getline
.
main
now looks something like
int main() {
cout << "Please enter a word, or a series of words: " << endl;
cin.getline(answer, sizeof(answer));
max = cin.gcount();
reverse();
lower();
upper();
system("pause");
return 0;
}
Whole bunch of stuff can go wrong at this point.
using namespace std;
can wreak havoc on the max
because of possible collisions with std::max
. In general, avoid using namespace std;
The few letters it saves you from typing often are recovered by the time wasted debugging the weird errors it can introduce.
isupper(answer[i]);
doesn't do anything useful as others have noted in the comments. You want
answer[i] = toupper(static_cast<unsigned char>(answer[i]));
See Do I need to cast to unsigned char before calling toupper(), tolower(), et al.? for why that insane-and-pointless-looking cast may be necessary. Thank you HolyBlackCat for bringing that to my attention.
Self assignments like
answer[i] = answer[i];
are pointless for reasons that should be obvious once you stop and think about it.
Likewise
else if (isspace(answer[i])) {
isspace(answer[i]);
}
May not be particularly useful. If answer[i]
is a space, set it to a space? It's already a space. What it would do is replace other forms of whitespace, tabs and carriage returns, with a space. Newline has already been picked off by getline
. Also probably needs a cast similar to the one used in the toupper
example above. I'm still reading up on that.
As hinted at above,
cout << answer[max];
is not effective. It prints out one character, and if max
has been fixed, answer[max]
will be the terminating null. Instead print out the whole array.
cout << answer;
General suggestions:
Don't write much code at a time. Write a few lines, a function at the most, before compiling and testing. If you had tested
int main() {
cout << "Please enter a word, or a series of words: " << endl;
cin >> answer[max];
cout << answer;
}
You would have immediately seen data was not being read correctly. and fixed it before proceeding. By allowing errors to build up, you make it harder to find any one bug. You may correctly fix a bug only to find the fix undone or concealed by another bug.
Avoid using global variables. Try to place variables in the smallest possible scope. In this case, move answer
and max
into main
and pass them to the other functions as parameters. This makes it a lot easier to keep track of who set what variable and when. It also helps prevent accidental Variable Shadowing.