I'm writing a program in C++ that takes integers from the user until they press "x" to stop.
Then the program will print the number of positives, negatives and zeros.
But whenever the user inputs "x", the program goes into an infinite loop.
I tried removing the "ZEROS" part and just made counters for positives and negatives and it worked good. But I want to count the zeros.
I need to let the user enter numbers including 0 until they enter character x.
Here is my code:
#include <iostream>
using namespace std;
int main() {
int input, neg = 0, pos = 0, zer = 0;
char z;
do {
cout << "Input another positive/negative number or 'x' to stop\n";
cin >> input;
cin.ignore();
if (input > 0){
pos++;
} else if (input == 0){
zer++;
} else if(input < 0){
neg++;
}
} while (z!='x');
cout << "You entered " << pos << " positive numbers.\n";
cout << "You entered " << neg << " negative numbers.\n";
cout << "You entered " << zer << "Zeros.";
return 0;
}
By far the simplest way of getting numbers until a user enters something else is this:
int input = 0;
cout << "Input a positive/negative number or 'x' to stop\n";
while(cin >> input) {
//they entered a number, do stuff
if (input > 0)
pos++;
else if (input == 0)
zer++;
else if (input < 0)
neg++;
cout << "Input another positive/negative number or 'x' to stop\n";
}
//cin failed to read a number, probably because they entered a letter
//if they failed to enter a number, we need to clear the fail flag before we can use cin again
cin.setstate(cin.rdstate()&~std::ios_base::failbit);
cout << "You entered " << pos << " positive numbers.\n";
cout << "You entered " << neg << " negative numbers.\n";
cout << "You entered " << zer << "Zeros.";
I wouldn't recommend anything more complicated until you get very advanced with C++. Parsing input is immensely difficult to get correctly, and many experienced people get it wrong.
In order to correctly handle input errors and limit it so that only lower case x will break your loop, you need to do a lot of error checking:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
int neg = 0;
int pos = 0;
int zer = 0;
std::string line;
while (std::cin >> line)
{
if (line == "x")
{
break;
}
std::istringstream iss(line); // convert to a stringstream
int val = 0;
if (!(iss >> val)) // if we can load an int, do it, otherwise show and error message
{
std::cout << "Please enter a valid number!" << std::endl;
continue;
}
if (val > 0)
{
pos++;
}
else if (val < 0)
{
neg++;
}
else
{
zer++;
}
}
std::cout << "You entered " << pos << " positive numbers.\n"
<< "You entered " << neg << " negative numbers.\n"
<< "You entered " << zer << " zeros." << std::endl;
return 0;
}
The problem is that an object of type int may not read symbols as for exmaple 'x' from a stream. It expects digits in an input stream. So when a symbol that can not be in a number is encountered in an input stream an error is arised. The stream will have erroneous state. If you will try again and again to read a number the stream will give nothing due to its state and the fact that the next symbol is for example non-digit.
So there is no sense to compare variable input with 'x'.
I would rewrite your loop the following way
while ( true )
{
int input;
cout << "Input another positive/negative number or 'x' to stop: ";
if ( !( cin >> input ) ) break;
if (input > 0)
{
pos++;
} else if (input == 0)
{
zer++;
} else
{
neg++;
}
}
check this out
#include <iostream>
#include<string>
using std::string;
using std::getline;
using namespace std;
int main()
{
string input;
int neg = 0, pos = 0, zer = 0;
char z;
input = "";
int iVal = 0;
do
{
cout << "Input another positive/negative number or 'x' to stop\n";
getline(cin, input);
iVal = atoi(input.c_str());
if (input != "x" && input !="X")
{
if (iVal > 0)
{
pos++;
} else if (iVal == 0)
{
zer++;
} else if(iVal < 0)
{
neg++;
}
}
} while (input != "x" && input != "X");
cout << "You entered " << pos << " positive numbers.\n";
cout << "You entered " << neg << " negative numbers.\n";
cout << "You entered " << zer << " zeros.\n";
return 0;
system("pause");
}
IT goes into the loop for a few reasons
1)You declared input as an integer, for this purpose ypu would have to declare it as char data type in order to do your validation on it
2)You dont have a if condition for x eg else if (input =='x')
Related
this is the code i wrote for simple grading exams (im still a very beginner) but when i do a wrong input in (Grades) it doesnt go to the function i made which is called (FalseInput) to make the user able to re-enter the (Grades) any suggestions to how to solve?
and how to improve in general ?
here is an example of whats the problem :
Please Type Your Name : rafeeq
Please Insert The Grade : as (which is an input error)
you failed
thanks.
#include <iostream>
#include <string>
using namespace std;
char Name[30];
int Grades;
const int MinGrade(50);
void FalseInput() {
cout << "pleae enter the number again : ";
cin >> Grades;
if (Grades >= MinGrade) {
cout << Name << " : " << "you passed\n";
cout << Grades;
} else if (Grades < MinGrade and cin.fail() == 0) {
cout << "you failed\n";
} else if (cin.fail() == 1) {
cout << "its not a valid number\n";
cin.clear();
cin.ignore(1000, '\n');
cout << endl;
FalseInput();
}
}
int main() {
cout << "Please Type Your Name : ";
cin.getline(Name, 30);
cout << "Please Insert The Grade : ";
cin >> Grades;
if (Grades >= MinGrade) {
cout << Name << " : " << "you passed\n";
cout << "The Grade Achieved : " << Grades << "%";
} else if (Grades < MinGrade) {
cout << "you failed\n";
} else if (cin.fail() == 1) {
cout << "its not a valid number\n";
cin.clear();
cin.ignore(1000, '\n');
cout << endl;
FalseInput();
}
return 0;
}
You don't check if the extraction of an int succeeds here:
cin >> Grades;
You can check the state of the input stream after extraction like this and it needs to be the first condition or else the program will make the comparisons with MinGrade first and will get a true on Grades < MinGrade.
if(!(cin >> Grades)) {
if(cin.eof()) {
// You can't recover the input steam from eof so here you need
// to handle that. Perhaps by terminating the program.
}
cin.clear();
cin.ignore(1000, '\n');
cout << endl;
FalseInput();
} else if(Grades >= MinGrade) {
cout << Name << " : " << "you passed\n";
cout << "The Grade Achieved : " << Grades << "%";
} else if(Grades < MinGrade) {
cout << "you failed\n";
}
You do have a lot of unnecessary code duplication and you also use an array of char to read the name - but you have included <string> so I assume you're familiar with std::string. I suggest using that.
Simplification:
#include <iostream>
#include <limits>
#include <string>
int main() {
const int MinGrade = 50;
std::string Name;
int Grades;
std::cout << "Please Type Your Name : ";
if(std::getline(std::cin, Name)) {
while(true) {
std::cout << "Please Insert The Grade : ";
if(!(std::cin >> Grades)) {
if(std::cin.eof()) {
std::cout << "Bye bye\n";
break;
}
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "That's not a valid number!\nPlease enter the "
"number again!\n";
} else if(Grades >= MinGrade) {
std::cout << Name << " : " << "you passed\n";
std::cout << "The Grade Achieved : " << Grades << "%\n";
break;
} else { // no need to check "Grades < MinGrade" here
std::cout << "you failed\n";
break;
}
}
}
}
What is happening: When that string "as" is attempted to write to the integer Grades, cin.fail() is set and Grades has the default of 0 written to it (I think that's right)
C++ cin reading string into int type returns 0
All-in-All: Input validation is needed BEFORE you check it's values.
Here is one approach, check if cin was able to successfully convert:
https://www.hackerearth.com/practice/notes/validating-user-input-in-c/
Another approach would be to read cin into a string instead of int, then you can control how to convert/cast it to whatever form you want (more work, but being that you are new - you will learn a lot doing this).
Secondary Note: Your string of 50 characters for name - imagine what would happen if you wrote 60 characters of input. There will be more data than the container can hold, thus writing past the bounds and into his neighbor (could cause a segment fault, or worse - crazy unexpected behavior)
Why does this work? Using cin to read to a char array smaller than given input
So I am currently working on a program in c++. I have written the following function. The line where it says "//code here" is where my issue is. Basically the program allows the user to create their own quiz txt file. For the question "How many questions should the quiz have?" the user will enter a number that represents the amount of questions. The issue arises when the user input will have to be validated.
Can anyone help me create a loop that does the following?
makes sure the user enters only numbers.
makes sure the numbers entered are greater than 1.
gives the user an error message if they entered a non digit.
gives the user an error message if they entered a number less than 2.
the program validates if the user just presses the enter key.
Once that is all sorted out the program will set NumberOfQuestions equal to the user input after converting it to an int.
void WriteOutQuestions(string &QuizName)
{
ofstream WriteOut;
string filename = "";
string userInput = "";
int numberOfQuestions;
char userInputChar = '0';
bool IncludeCommments = false;
cout << "Name your file\n";
getline(cin, filename);
cout << "Now give your new quiz a title\n";
getline(cin, QuizName);
cout << "How many questions should the quiz have?\n";
getline(cin, userInput);
//code here
numberOfQuestions = stoi(userInput);
cout << "The quiz will contain " << numberOfQuestions << " questions." << endl;
cout<< "Would you like to include comments in any of the choices?\n";
cout << "[Y/y for yes N/n for No]\n";
getline(cin, userInput);
if (userInput == "y" && userInput == "Y")
IncludeCommments = true;
else
cout << "Comments disabled by user...\n";
WriteOut.open(filename + ".txt");
if (!WriteOut)
{
cout << "The file was not found...\n";
}
else
{
cout << "File was read!\n";
}
WriteOut << QuizName << endl;
WriteOut << numberOfQuestions << endl;
for (int i = 0; i < numberOfQuestions; ++i)
{
cout << "What is question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "Q" << i + 1 << " " + userInput << endl;
cout << "What is choice A for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "A) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice A for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice B for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "B) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice B for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice C for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "C) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice C for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "What is choice D for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << "D) " + userInput << endl;
if (IncludeCommments == true)
{
cout << "What is the comment for choice D for question number " << i + 1 << "?\n";
getline(cin, userInput);
WriteOut << userInput << endl;
}
else
WriteOut << "" << endl;
cout << "Which choice is the right one? [A, B, C or D]\n";
getline(cin, userInput);
while (userInput != "a" && userInput != "A" && userInput != "b" && userInput != "B" &&
userInput != "c" && userInput != "C" && userInput != "d" && userInput != "D")
{
cout << "Only A-D is accepted\n";
}
userInputChar = userInput[0];
if (userInputChar > 96)
{
userInputChar -= 32;
}
userInput = userInputChar;
cout << "userinput contains " << userInput << endl;
cout << "userinputchar contains " <<userInputChar << endl;
WriteOut << userInput << endl;
}
WriteOut.close();
}
first of all you need to change the && in the below code to || to run the code the code correctly
if (userInput == "y" && userInput == "Y")
IncludeCommments = true;
else
cout << "Comments disabled by user...\n";
and coming to the validation you can maintain a flag variable after taking userinput
cout << "How many questions should the quiz have?\n";
getline(cin, userInput);
int length=userInput.length(); //gives the length of string entered
int flag=0; //flag variable
for(int i=0;i<length;i++)
{
if((!(userinput[i]>='0'&&userinput[i]<=9))||isspace(s[i])) //i am
considering space is not a problem
{
flag=1;
}
}
if(flag!=0)
{
cout<<"error:Non digit is entered"<<endl
}else
{
int numberofquestions = stoi(userinput);
if(numberofquestions<=1){
cout<<"error:number less than 2 is entered"<<endl;
}
}
There are so many options that it is difficult to make a good recommendation.
I will show you several solutions. The first part has always the same approach:
We run a do loop
First we instruct the user, what to do
Then we read the input
Then we, check, if all are digits
If we have all digits, then we convert to a number
and check, if the number is greater than 1
If we find an error, we loop again. Let`s look at the options in the code below
Index based for loop and compare with character digits
Index based for loop and use of isdigit function
Range based for loop and use of isdigit function
all_of algorithm and use of isdigit function
regex. Will also handle empty lines
Extened regex. Will also handle empty lines AND will check if number > 1
Options 1-4 need an additional check for an empty line. User presses just enter.
Please see code with all options:
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
#include <regex>
int main() {
// We try to get input from the user and run a loop as long as it is not OK
bool inputIsOK{};
// This is the number of questions that we want to read
int numberOfQuestions{};
// Ask for valid input from user
do {
// Assume valid input
inputIsOK = true;
// Instruct user
std::cout << "\nHow many questions should the quiz have? Enter a number > 1.\n";
// Read complete line from the user
std::string line{};
if (std::getline(std::cin, line)) {
// Check, if all characters are valid (digits)
// Option 1 -------------------------------------------------------------------
// Index based for loop and compare with character digits
for (size_t i{}; i < line.length(); ++i) {
if (line[i] < '0' || line[i] > '9') {
inputIsOK = false;
std::cerr << "\nError 1: Please enter digits only\n";
break;
}
}
// Option 2 -------------------------------------------------------------------
// Index based for loop and use of isdigit function
for (size_t i{}; i < line.length(); ++i) {
if (not std::isdigit(line[i])) {
inputIsOK = false;
std::cerr << "\nError 2: Please enter digits only\n";
break;
}
}
// Option 3 -------------------------------------------------------------------
// Range based for loop and use of isdigit function
for (const char c : line) {
if (not std::isdigit(c)) {
inputIsOK = false;
std::cerr << "\nError 3: Please enter digits only\n";
break;
}
}
// Option 4 -------------------------------------------------------------------
// all_of algorithm and use of isdigit function
if (not std::all_of(line.begin(), line.end(), isdigit)) {
inputIsOK = false;
std::cerr << "\nError 4: Please enter digits only\n";
}
// Option 1-4 -----------------------------------------------------------------
// For option 1 to 4 you need to additionally check for empty line
if (inputIsOK && line.length() == 0) {
inputIsOK = false;
std::cerr << "\nError 5: Please enter digits only\n";
}
// Option 5 -------------------------------------------------------------------
// regex. Will also handle empty lines
if (not std::regex_match(line, std::regex("\\d{1,6}"))) {
inputIsOK = false;
std::cerr << "\nError 6: Please enter digits only (max 6)\n";
}
// Option 6 -------------------------------------------------------------------
// Extened regex. Will also handle empty lines AND will check if number > 1
if (not std::regex_match(line, std::regex(R"([2-9]|([1-9][0-9]{1,6}))"))) {
inputIsOK = false;
std::cerr << "\nError 7: Please enter number > 1 (Max 6 digits)\n";
}
// End Option -----------------------------------------------------------------
// Check, if number is > 1
if (inputIsOK) {
numberOfQuestions = std::stoi(line);
if (numberOfQuestions < 2) {
inputIsOK = false;
std::cerr << "\nError 8: Number too small. Enter number > 1\n";
}
}
}
else {
std::cerr << "\nError: General problem with input\n";
inputIsOK = false;
std::cin.clear();
}
} while (not inputIsOK);
return 0;
}
You can choose whatever option you want.
However. I would not use one of the above.
I would use the IOstream facilities and directly read an unsigned integer. If the input is wrong, the state of std::cin will goto fail and indicate the problem.
So, you could use that instead:
#include <iostream>
#include <limits>
int main() {
// We try to get input from the user and run a loop as long as it is not OK
bool inputIsOK{};
// This is the number of questions that we want to read
unsigned int numberOfQuestions{};
// Ask for valid input from user
do {
// Instruct user
std::cout << "\nHow many questions should the quiz have? Enter a number > 1.\n";
// Get input. Directly as number
inputIsOK = (std::cin >> numberOfQuestions) && (numberOfQuestions > 1);
// In case of error. Show message
if (not inputIsOK) {
std::cerr << "\nError 1: Wrong input\n";
std::cin.clear(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} while (not inputIsOK);
return 0;
}
The ignore function will delete all the trash taht maybe still in the input buffer.
I'm trying to display "invalid option" when the user enters a letter instead of a number. I tried using the isalpha() function but I get an infinite loop showing 0 Invalid option!try again:. The 0 from the output is displayed when entering a letter. When I actually type in the number 0 the message is displayed and the loop is exited.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cctype>
using namespace std;
int main() {
// Vaules do not change
const int minNum = 1;
const int maxNum = 100;
int userInput;
// Changes every second
srand(time(0));
// Random number is stored
const int answer = minNum + (rand() % maxNum);
cout << answer << endl; // For testing purposes
cout << "Guess a number 1-100: ";
cin >> userInput;
cout << endl;
if(userInput == answer) {
cout << "Correct!\n\n";
}
while(userInput != answer) {
if(userInput < 1 || userInput > 100 || isalpha(userInput)) {
cout << userInput << " Invalid option!\ntry again: ";
cin >> userInput;
cout << endl;
}
else if(userInput < answer) {
cout << userInput << " is too low!\ntry again: ";
cin >> userInput;
cout << endl;
}
else if(userInput > answer) {
cout << userInput << " is too high!\ntry again: ";
cin >> userInput;
cout << endl;
}
}
cout << userInput << " is correct!\n\n";
return 0;
}
When you need to deal with user input differently based on some logic, your best option is to:
Read lines of text. Figure out what to do when there is no more input.
Process each line of text using custom logic.
In your case, you could use:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cctype>
using namespace std;
int main() {
// Vaules do not change
const int minNum = 1;
const int maxNum = 100;
int userInput;
// Changes every second
srand(time(0));
// Random number is stored
const int answer = minNum + (rand() % maxNum);
cout << answer << endl; // For testing purposes
std::string line;
cout << "Guess a number 1-100: ";
while ( getline(std:::cout, line ) )
{
// Deal with empty lines.
if ( line.size() == 0 )
{
continue;
}
// If the first character is a letter ...
if(isalpha(line[0])) {
cout << line << "\n Invalid option!\ntry again: ";
continue;
}
// Extract the number from the line using a stringstream.
// If there is a problem extracting the number ...
std::istringstream str(line);
if ( !(str >> userInput ) )
{
cout << line << "\n Invalid option!\ntry again: ";
continue;
}
cout << endl;
// Check the user input against the random answer.
if(userInput == answer) {
cout << "Correct!\n\n";
}
else if(userInput < 1 || userInput > 100 ) {
cout << userInput << " Invalid option!\ntry again: ";
}
else if(userInput < answer) {
cout << userInput << " is too low!\ntry again: ";
}
else if(userInput > answer) {
cout << userInput << " is too high!\ntry again: ";
}
cout << "Guess a number 1-100: ";
}
cout << userInput << " is correct!\n\n";
return 0;
}
I'm a very beginner in C++ and I'm actually following the Google tutorial.
Trying to go a little further with the second example, here is my problematic : checking if the input is a number and, if not, being able to restate it in the error message.
Here is a way I used to solve that but the code length tells me that there is a shorter way :
#include <cstddef>
#include <iomanip>
#include <iostream>
#include <stdlib.h>
using namespace std;
bool IsInteger(string str) {
size_t non_num_position = str.find_first_not_of("0123456789-");
size_t sign_position = str.find_first_of("-", 1);
if (non_num_position == string::npos && sign_position == string::npos) {
return true;
}
return false;
}
void Guess() {
int input_number = 0;
string input_string;
do {
cout << "Try to guess the number between 0 and 100 (type -1 to quit) : ";
cin >> input_string;
if (!IsInteger(input_string)) {
int input_string_length = input_string.size();
cout << "Sorry but « " << input_string << " » is not a number." << endl;
cin.clear();
cin.ignore(input_string_length, '\n');
continue;
}
input_number = atoi(input_string.c_str());
if (input_number != -1) {
cout << "You chose " << input_number << endl;
}
} while (input_number != -1);
cout << "The End." << endl;
}
int main() {
Guess();
return 0;
}
Here is the shorter way I try to follow but cin seems to be "emptied" once assigned to input_number (because of the bitwise operator ?) :
void Guess() {
int input_number = 0;
string input_string;
do {
cout << "Try to guess the number between 0 and 100 (type -1 to quit) : ";
if (!(cin >> input_number)) {
getline(cin, input_string);
cout << "Sorry but " << input_string << " is not a number." << endl;
cin.clear();
cin.ignore(100, '\n');
continue;
}
if (input_number != -1) {
cout << "You chose " << input_number << endl;
}
} while (input_number != -1);
cout << "The End." << endl;
}
SOLUTION :
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
void Guess() {
int input_number = 0;
string input_string;
do {
cout << "Try to guess the number between 0 and 100 (type -1 to quit) : ";
cin >> input_string;
try {
input_number = stoi(input_string);
if (input_number != -1) {
cout << "You chose " << input_number << endl;
}
}
catch (const exception&) {
cout << "Sorry but " << input_string << " is not a number." << endl;
}
} while (input_number != -1);
cout << "The End." << endl;
}
int main() {
Guess();
return 0;
}
The problem with your first attempt is that IsInteger is unnecessarily complicated and long. Otherwise, you had the right idea. Your second attempt is much less correct.... once you read from cin, the data is gone. So, as in the first attempt, you need to store the data in a string.
Here's an example which is a little shorter and doesn't need IsInteger at all:
size_t p = 0;
int input_number = std::stoi(input_string, &p);
if (p < input_string.length())
{
cout << "Sorry but " << input_string << " is not a number." << endl;
conitnue;
}
stoi's second argument tells you where the conversion to integer stopped working. So if there was non-int data in the string (such as '123abc') then p will be somewhere before the end of the string. If p is at the end, then the whole string must have been a number.
SO I want to be able to invalidate all user input except a certain word, like 'K' or 'C'. I'm not sure at all how to do this. So if they mispell it to "celcius" or "husdhfjae", my program would say "Input invalid, please enter K or C."
Please nothing too complicated, because I just started. Thank you :)
// CS 575,HW #1B, Ravela Smyth
// This program converts from Fahrenheit to Celsius or Kelvin
#include <iostream>
#include <string>
using namespace std;
int main() {
string input;
double Fahrenheit, celsius, kelvin;
cout << "Hi! What is the weather today in Fahrenheit?? " << endl;
cin >> Fahrenheit;
cout << "Would you like to convert this temperature to Celsius or Kelvin? (C/K)" << endl;
cin >> input;
if (input == "C")
{
celsius = (5 * (Fahrenheit - 32)) / 9;
cout << "Today's weather in Celsius is " << celsius << " degrees! " << endl;
}
else if (input == "c")
{
celsius = (5 * (Fahrenheit - 32)) / 9;
cout << "Today's weather in Celsius is " << celsius << " degrees! " << endl;
}
else if (input == "K")
{
kelvin = (5 * (Fahrenheit + 459.67)) / 9;
cout << "Today's weather in Kelvin is " << kelvin << " degrees!" << endl;
}
else if (input == "k")
{
kelvin = (5 * (Fahrenheit + 459.67)) / 9;
cout << "Today's weather in Kelvin is " << kelvin << " degrees!" << endl;
}
return 0;
}
Usually user inputs are checked using while or do...while loops.
The idea is simple, you always get back to the same error message and read again the input until it is correct.
The advantage of placing the valid options in the single string is to allow easy addition or removal of the options without dealing with long if conditions.
I believe something simple like this will do the job:
std::string valid_options("kKcC");
std::string input;
bool illegal_input;
std::cout << "Would you like to convert this temperature to Celsius or Kelvin? (C/K)" << std::endl;
std::cin >> input;
// check that only one letter was provided and it belongs to the valid options
while (input.size() != 1 || valid_options.find(input) == std::string::npos)
{
std::cout << "Input invalid, please enter K or C.\n";
std::cin >> input;
}
First, you can do something like if(input == "C" || input == "c")
Or you can convert the input to lower/upper case
Second, you can add an else statement that says something like "please enter a valid command". Play around with it, you can even use loops to wait for correct input!
My approach is to test the input against a container of all valid inputs.
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
bool valid(std::string s,std::vector<std::string> y)
{
std::sort(y.begin(), y.end());
return std::binary_search(y.begin(), y.end(), s);
}
int main()
{
std::string s;
do
{
std::cout << "Enter K or C: ";
std::cin >> s;
} while (!valid(s, { "K","C","k","c" }));
std::cout << "good!" << std::endl;
return 0;
}
You need a while loop. This is probably the simplest way to do it.
#include <iostream>
#include <string>
int main()
{
std::string word;
std::cin >> word;
//Keep asking for a word until this condition is false, i.e.
//word will be equal to one of these letters
while(word != "C" && word != "c" && word != "K" && word != "k")
{
std::cout << "Invalid temperature type: " << word << " Use 'K' or 'C'" << std::endl;
std::cin >> word;
}
if (word == "C" || word == "c")
{
std::cout << "Celsius" << std::endl;
}
else if (word == "K" || word == "k")
{
std::cout << "Kelvin" << std::endl;
}
}
I had the same problem while getting the correct user input for that i wrote a simple solution i hope it will be helpfull for everyone getting started with c++.
//get user input
char input;
cin >> input;
//convert the input to lowercase
char Temp = tolower(input);
//check the input (not valid input will clear the user input)
while(!(cin >> input) || ((Temp != 'c') &&( Temp != 'k')){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please, try again: ";
}
//evalute input cases
switch (Temp)
{
case 'c':
/* celcius */
break;
case 'k':
/* Kelvin */
break;
}