the isupper(), islower(), toupper(), tolower() functions not working in c++ - c++

I have a code fragment something like this:
char choice;
do
{
cout << "A. Option 1" << endl;
cout << "B. Option 1" << endl;
cout << "C. Option 1" << endl;
cout << "D. Option 1" << endl;
cout << "Option: ";
cin >> choice;
if(islower(choice) == 0){ toupper(choice); } // for converting Lower alphabets to Upper alphabets so as to provide flexibility to the user
}while((choice != 'A') && (choice != 'B') && (choice != 'C') && (choice != 'D'));
but it does not converts the Lower alphabets to Upper alphabets... I don't know why... The OS I am using is Windows 7 and the Compiler is Visual C++(please note that I have tested this code in other compilers to but the same problem)...

You should use the returned value, toupper takes a character by value (not reference) and returns the upper case result:
choice = toupper(choice);
^^^^^^^^
Also, the condition should be inverted:
if (islower(choice)) // not: if(islower(choice) == 0)
Use this code, toupper itself checks if the character is lower case or not:
cin >> choice;
choice = toupper(choice);

This line of code
if(islower(choice) == 0){ toupper(choice); }
should be re-write as below,
if(islower(choice)){ choice = toupper(choice); }
The function,
int toupper ( int c );
Return Value
The uppercase equivalent to c, if such value exists, or c (unchanged) otherwise. The value is returned as an int value that can be implicitly casted to char.
toupper

islower and isupper tells whether character is upper case or lower case or not.
toupper or tolower does not convert. It takes int parameter and returns an int which is converted character.
To convert use the following:
choice = toupper(choice);

Related

When the input is a character or a word, it doesn't display "Invalid input"

When the input is >2 or <0 it display "Invalid input.". But when the input is an alphabet or a word it does not display "Invalid input."
int main()
{
int userInput, gesture;
cout << "Rock(0), Paper(1), Scissor(2): ";
cin >> userInput;
srand(time(0));
gesture = rand() % 3;
if (isdigit(userInput) && userInput >= 0 || userInput <= 2) //I think it's a logic error, but idk how to fix it.
{
switch (gesture)
{
case (0):
if (userInput == gesture)
cout << "The computer is rock. You are rock too. It is a draw." << endl;
else if (userInput == 1 && gesture == 0)
cout << "The computer is rock. You are paper. You win." << endl;
else if (userInput == 2 && gesture == 0)
cout << "The computer is rock. You are scissor. You lose." << endl;
break;
}
}
else
cout<<"Invalid input.";
return 0;
}
Let's look at this:
if (isdigit(userInput) && userInput >= 0 || userInput <= 2)
The signature of isdigit is this:
int isdigit( int ch );
so one might be fooled into thinking that it expects an int, like 1 or 34. In reality, it expects an argument of type unsigned char converted into an int. Why, you'd ask? Because it was included into C++ via the standard library of the C language, and in C there's a special marker EOF that marks the "end of file" in a stream of characters (just like \0 marks the end of a string). The problem is that EOF cannot be represented as a char, hence many C functions designed to handle strings accept ints. The only thing we know about EOF is that it is negative.
So, the usual usage of isdigit is something like this:
unsigned char c = '0';
// ...
if (isdigit(c)) { /* ... */ }
What you should do, then?
Well, the simpler, the better
if (userInput >= 0 && userInput <= 2)
If you want to check for completely invalid user input, check the state of cin
if (std::cin && userInput >= 0 && userInput <= 2)
An alternative is to initialize userInput with a plain wrong value, e.g. with -1. If cin fails, you'll know something wrong has happened anyway, because userInput woul'd have an ivalid value -1.
Use std::cin.clear() to clear the "fail state" flag in std::cin and unblock it.

Getting junk when trying to return a string

I'm probably an idiot, I know. This is probably a duplicate, but for the life of me I couldn't find an answer after looking for over an hour. I guess I don't know how to phrase a search. All I want is to be able to print out a string from a function based on user input. This isn't part of the program I'm building right now, but it illustrates my problem.
#include "../std_lib_facilities.h"
string make_name()
{
string name;
int selection;
cout << "Enter 1 steve. Enter 2 Mike.\n\n";
cin >> selection;
if (selection == '1')
name = "Steve";
else if (selection == '2')
name = "Mike";
return name;
}
int main()
{
cout << "Make a name\n";
make_name();
cout << "Your name is " << make_name;
keep_window_open();
}
Instead of printing Mike or Steve, it prints nonsense. I've been working on all the other parts of my program, but now this is the only problem I have. So, lay into me. What am I doing wrong?
The reason you're getting garbage printed is because at this line in main:
cout << "Your name is " << make_name;
You're printing out the address of the function 'make_name', as opposed to the result of calling it.
The fix is to capture the result of calling the function and print that out instead:
int main()
{
cout << "Make a name\n";
string name = make_name();
cout << "Your name is " << name;
keep_window_open();
}
One other latent issue is inside of your 'make_name' function, your two conditions:
if (selection == '1')
name = "Steve";
else if (selection == '2')
name = "Mike";
You're comparing 'selection', which is an int, to the ASCII characters 1 and 2, which is not what you want.
Change that to:
if (selection == 1)
name = "Steve";
else if (selection == 2)
name = "Mike";
and you should have the desired result.
Note: Also, consider initialising your 'selection' variable to 0. That should prevent unexpected results if someone were to input "hello", instead of a number.
This is because of
if (selection == '1')
Here you are comparing an int with char. That means value of '1' would be the ASCII value of this character which is not 1.
Correct conditional statement should be:-
if (selection == 1)

What's wrong with the following C++ code involving input and string?

#include <iostream>
typedef int temperature;
temperature celsiustemperature[4];
int main()
{
using namespace std;
cout << "Enter a start temperature in celsius: ";
cin >> celsiustemperature[0];
cout << "Enter an end temperature in celsius: ";
cin >> celsiustemperature[1];
cout << "You printed " << celsiustemperature[0] << " and " << celsiustemperature[1] << "." << " Is this correct?" << endl;
char szYesOrNo;
cin >> szYesOrNo;
switch (szYesOrNo)
{
case "yes":
cout << "win";
break;
case "no":
cout << "winner";
break;
}
return 0;
}
I cannot figure out what is wrong with the following code. Sorry for not adding comments; I want it to print win if the user inputs yes and winner if user inputs no.
This won't compile, because szYesOrNo is a char, and you are comparing it with string literals in your switch statement. String literals are of type const char[], which cannot be directly compared to char.
Use std::string instead of a char:
std::string szYesOrNo;
This will also force you to remove the switch, because switch cannot operate on a string value (also notice, that your switch does not have a default case, so it won't handle incorrect input). Just do it this way:
if (szYesOrNo == "yes")
{
cout << "win";
}
else if (szYesOrNo == "no")
{
cout << "winner";
}
else
{
// Handle wrong input...
}
You can't switch on a string. Only on an integer-like type (ints, enums, chars, longs).
The main problem with your code is that you declare a variable as char szYesOrNo; which can only hold ONE symbol, such as a letter, but then expect the character to enter a whole word. You should use a string to do this instead. When you fix that, you will need to use if statements instead of a switch statement to make decisions.
First of all, szYesOrNo is a single char and so can only contain one character. When you do cin >> szYesOrNo;, you are only reading y or n.
Second, you're trying to use a switch statement to compare this single char to the string literals "yes" and "no". This comparison doesn't make sense. The string literals are of type "array of N const char".
Instead, use std::string like so:
string szYesOrNo;
cin >> szYesOrNo;
if (szYesOrNo == "yes") {
cout << "win";
} else if (szYesOrNo == "no") {
cout << "winner";
}
szYesOrNo is a character, so you cannot switch it in a case of "yes" which is a string ( 3 characters )
char szYesOrNo;
This is a single character.
switch (szYesOrNo)
{
case "yes":
This will compare the value of the single character with the address of the string "yes", which isn't what you want.
Either input to a string, or compare chars.
To compare chars:
switch (szYesOrNo)
{
case 'y':
To compare strings, you can't use a switch statement. You could use nested if/else:
string szYesOrNo;
if(szYesOrNo == "yes") {
cout << "win";
} else if(szYesOrNo == "no") {
cout << "winner";
}
You can use == when comparing a string to a char[] (which is what "yes" is). string makes sure the contents are compared rather than just the addresses.

using user input such as YES and NO to control program flow in C++

I'm making a small program that uses a if else statement, but instead of using numbers to control the flow i want to be able to make the control work with with yes and no;
for example:
cout << "would you like to continue?" << endl;
cout << "\nYES or NO" << endl;
int input =0;
cin >> input;
string Yes = "YES";
string No = "NO";
if (input == no)
{
cout << "testone" << endl;
}
if (input == yes)
{
cout << "test two" << endl;
//the rest of the program goes here i guess?
}
else
{
cout << "you entered the wrong thing, start again" << endl;
//maybe some type of loop structure to go back
}
but I can't seem to get any variations of this to work, i could make the user type a 0 or 1 instead but that seems really stupid, i'd rather it be as natural as possible, users don't speak numbers do they?
also i need to be able to simply add more words, for example "no NO No noo no n" all would have to mean no
hopefully that makes some sense
also i would love to make this using a window but i've only learned basic c++ so far not even that and i cant find any good resources online about basic windows programming.
You're not reading in a string, you're reading in an int.
Try this:
string input;
instead of
int input = 0;
Also, C++ is case-sensitive, so you can't define a variable called Yes and then try to use it as yes. They need to be in the same case.
btw, your second if statement should be an else if, otherwise if you type in "NO" then it will still go into that last else block.
First of all, input must be std::string, not int.
Also, you've written yes and no wrong:
v
if (input == No)
// ..
// v
else if (input == Yes)
^^^^
If you want your program to work with "no no no ..", you could use std::string::find:
if( std::string::npos != input.find( "no" ) )
// ..
The same with "Yes".
Also, you could do this to be almost case-insensitive - transform the input to upper-case letters (or lower, whatever ), and then use find.This way, yEs will be still a valid answer.
bool yesno(char const* prompt, bool default_yes=true) {
using namespace std;
if (prompt && cin.tie()) {
*cin.tie() << prompt << (default_yes ? " [Yn] " : " [yN] ");
}
string line;
if (!getline(cin, line)) {
throw std::runtime_error("yesno: unexpected input error");
}
else if (line.size() == 0) {
return default_yes;
}
else {
return line[0] == 'Y' || line[0] == 'y';
}
}
string input;
cin >> input;
if (input == "yes"){
}
else if (input == "no"{
}
else {
//blah
}

Input accepting char when it should be string?

I am new to C++ and am making a simple text RPG, anyway, The scenario is I have a "welcome" screen with choices 1-3, and have a simple IF statement to check them, here:
int choice;
std::cout << "--> ";
std::cin >> choice;
if(choice == 1) {
//..
That works fine, but if someone enters a letter as selection (instead of 1, 2 or 3) it'll become "-392493492"or something and crash the program. So I came up with:
char choice;
std::cout << "--> ";
std::cin >> choice;
if(choice == 1) {
//..
This works kinda fine, but when I enter a number it seems to skip the IF statements completely.. Is the char "1" the same as the number 1?
I get a compiler error with this (ISO-CPP or something):
if(choice == "1")
So how on earth do I see if they entered 1-3 correctly!?
1 is an int
'1' is a char
"1" is a char array
I guess you want to compare with '1'.
Choice doesn't become "-392493492" or something, it starts as that value (you didn't initialise it, so the initial value is unspecified) and is never set to anything else because the >> fails. You should check that such operators succeed, which is quite easy to do:
if (std::cin >> choice) {
switch (choice) {
case 1: // ...
case 2: // ...
case 2: // ...
default: // report error
}
}
Unfortunately 1 and '1' are not the same.
Look up your favorite ASCII table to know the integer value that represents the character "1" and you'll see it for yourself: '1' is mapped to 49.
There is another issue with this code "" denotes a C-string (const char*) whereas '' denotes a single character.
Here is your code reworked:
char choice = 0;
if (cin >> choice) // check success
{
switch(choice) // choose
{
case '1': { /**/ break; }
case '2': { /**/ break; }
case '3': { /**/ break; }
default:
cout << choice
<< " is not a valid choice, please press 1, 2 or 3 and Enter"
<< endl;
}
}
I switched to switch because it's more natural than a chain of else-if for generic enumeration.
if(choice == '1')
And to answer your question, the ascii valyue for 1 is not equal to 1, but is equal to 49:
'1' == 49
choice is a char so you should use '1' to check. "1" represents a string with 1 character in it.
A value in double quotes is interpreted as a string (of type char*, which is incompatible with a char), while in single quotes it is interpreted as a char:
if(choice == '1')
The integer representation of the char'1' is not 1, but 49 (in ASCII). So you could also write
if(choice == 49)
Also, you should have an else branch to display an error message or something, and prevent the program from continuing in case an invalid input has been entered.