C++ Ask user if input is correct error - c++

Im trying to add code so if the user mistypes they can go back in the program and retype the input but im not sure if the code i found and used is correct. here it is in my function:
/********************************************/
// Name: inspools /
// Description: Ask for and get number of /
// spools /
// Parameters: N/A /
// Reture Value: spoolnum /
/********************************************/
int spoolnum()
{
int spoolnum;
char type;
cout << "Number of spools to be shipped: " << endl;
cin >> spoolnum;
cout << spoolnum << " spool(s) of wire will be shipped" << endl;
cout << "Is this correct? [y/n] ";
cin >> type;
if ('n') << spoolnum;
if ('y') break;
return spoolnum ;
}

You said you searched for loops, but I don't buy it. I imagine you are pretty new at programming. I'm going to give you the answer but not without some explanation first.
How While Loops Work
From Wikipedia:
In most computer programming languages, a while loop is a control flow
statement that allows code to be executed repeatedly based on a given
boolean condition. The while loop can be thought of as a repeating if
statement.
Your Problem
Your problem is that you want to keep making the user enter a choice until they enter y. To do this, you need at least a WHILE loop, or as other commenters have said a DO/WHILE loop.
I have never preferred DO/WHILE loops but others do prefer it.
The problems you may have with the below code is that you have more than just y returned in cin such as a newline (\n) character. You will have to handle that condition.
int spoolnum()
{
int spoolnum = 0;
char type = 'n';
while (type != 'y') {
cout << "Number of spools to be shipped: " << endl;
cin >> spoolnum;
cout << spoolnum << " spool(s) of wire will be shipped" << endl;
cout << "Is this correct? [y/n] ";
cin >> type;
}
return spoolnum;
}
or the alternative DO/WHILE:
int spoolnum()
{
int spoolnum = 0;
char type = 'n';
do {
cout << "Number of spools to be shipped: " << endl;
cin >> spoolnum;
cout << spoolnum << " spool(s) of wire will be shipped" << endl;
cout << "Is this correct? [y/n] ";
cin >> type;
} while (type != 'y');
return spoolnum;
}
In the above code, I removed your if ('n') << spoolnum; because frankly it does not make sense.
I also removed if ('y') break; because the while(...) loop will break once the condition is met, which is type equal to 'y'.

Related

C++ If/Else loop problems

Checking user input. If the incorrect input is entered, it loops fine. If the correct input is entered, It has 2 be entered again in order for it to register. Help?
int deposit;
cout << "How much do you want to deposit?" << endl;
cin >> deposit;
if (!(cin >> deposit)) { // If the input is not equal to the data type of
// deposit
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid Input" << endl;
} else {
while (infile >> u >> p >> b) {
if (checkUser == u) {
int newBalance;
cout << "Your amount of $" << deposit << " has been added to your account"
<< endl;
int fileBalance;
stringstream convert(b); // object from the class stringstream
convert >> fileBalance; // the objects has the value of B and
newBalance = fileBalance + deposit;
outfile << checkUser << ' ' << checkPass << ' ' << newBalance << endl;
} else {
outfile << u << ' ' << p << ' ' << b << endl;
}
}
}
You're entering input twice because you go through cin>>deposit at least twice:
cout << "How much do you want to deposit?" << endl;
cin >> deposit;
if (!(cin >> deposit)) {
Just get rid of the first cin:
cout << "How much do you want to deposit?" << endl;
if (!(cin >> deposit)) {
Also, have a look at setting up clang-format with your code editor or IDE. It makes your code look nice without effort and will help you spot errors. There's also an online version available here: http://format.krzaq.cc/
It's because here:
if(!(cin>>deposit))
you're re-reading from standard input. When you first do cin>>deposit, you've already stored the value in the variable, so you just have to check the deposit variable, or whatever you want to do with the inserted data.
Another, cleaner, way of doing it is to just avoid the first cin>>deposit statement.

C++ Program glitch?

I need help debugging my code. So I made a program that adds and subtracts numbers but when I implemented a do-while loop to replay the program, the actual program closes and does not perform the do-while loop and does not replay the program. Is their something wrong with my code?
P.S. I am also using codeblocks IDE
#include <iostream>
using namespace std;
int main()
{
// Addition and Subtraction Calculator
int a_number, number1, number2, sum, number3, number4, subsum, again;
// subsum = subtracted sum
// number1 and number2 are variables that hold the users input for addition
// number3 and number4 are variables that hold the users input for subtraction
do
{
cout << "Addition & Subtraction Calculator" << endl;
cout << "-------------------------------------------" << endl;
cout << "1. Addition" << endl;
cout << "2. Subtraction" << endl;
cout << "Please enter a number [1 or 2]" << endl;
cin >> a_number;
while (a_number < 1 || a_number > 2)
{
cout << "Please enter either 1 or 2" << endl;
cin >> a_number;
}
switch (a_number)
{
case 1:
cout << "Please enter a number" << endl;
cin >> number1;
cout << "Please enter another number" << endl;
cin >> number2;
sum = (number1 + number2);
cout << "The sum is " << sum << endl;
break;
case 2:
cout << "Please enter a number" << endl;
cin >> number3;
cout << "Please enter another number" << endl;
cin >> number4;
subsum = (number3 - number4);
cout << "The answer to the subtraction problem is: " << subsum << endl;
break;
}
cout << "Do you want to try again? [y/n]" << endl;
cin >> again;
}
while (again == 'y' || again == 'n');
return 0;
}
OK. So the OP is using an int where they should have used a char. That covers the immediate problem. int again should be char again.
But there is an important point the other answers have missed.
int again;
cin >> again;
The user input will be converted into an integer as required by again. Inputting y or n fails to convert to an integer as neither y nor n are numbers and cannot be converted. again remains unchanged, keeping whatever junk value happened to be sitting at that spot in memory and might actually be a y or an n, but more importantly cin is now in an error state that needs to be cleared before continuing.
cin would have notified the OP of this if it had been tested. So let's test it.
int again;
if (cin >> again)
{
// got good input. Do something with it.
}
else
{
// got bad input.
cin.clear();
// that bad input is still in the buffer and needs to be removed
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// the above line will wipe out everything to the end of the stream or
// end of line, whichever comes first.
}
Why this is important: Because the OP is doing a lot of numeric input with cin and none of it is checked for validity. For example:
cout << "Please enter a number [1 or 2]" << endl;
cin >> a_number;
The program is broken completely and cannot exit without a kill signal if the user types in anything but a number.
Always check the error state and return codes. They are there to help. Always validate user input before using it. Users are evil and will try to break your program. Don't let them.
use char again; instead of int again;
in your code again is int and when in (again == 'y' || again == 'n')you compare again (an int) with a char, that does not make sense
You need to change the again variable to a char datatype because you need to store text. Something like this:
char again;
You also need to change the while statement to:
while(again != "n");
Or
while(again == "y");

How can I avoid bad input from a user?

I am a very newbie programmer, so I don't really know much about writing code to protect the application.. Basically, I created a basicMath.h file and created a do while loop to make a very basic console calculator (only two floats are passed through the functions). I use a series of if and else if statements to determine what the users wants to do. (1.add, 2.subtract, 3.multiply, 4.divide) I used a else { cout << "invalid input" << endl;} to protect against any other values, but then I tried to actually write a letter, and the program entered a infinite loop. Is there anyway to protect against users who accidentally hit a character instead of a number?
`#include <iostream>
#include "basicMath.h"
using namespace std;
char tryAgain = 'y';
float numOne = 0, numTwo = 0;
int options = 0;
int main()
{
cout << "welcome to my calculator program." << endl;
cout << "This will be a basic calculator." << endl;
do{
cout << "What would you like to do?" << endl;
cout << "1. Addition." << endl;
cout << "2. Subtraction." << endl;
cout << "3. Multiplication" << endl;
cout << "4. Division." << endl;
cin >> options;
if (options == 1){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " + " << numTwo << " = " << add(numOne, numTwo) << endl;
}
else if (options == 2){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " - " << numTwo << " = " << subtract(numOne, numTwo) << endl;
}
else if (options == 3){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " * " << numTwo << " = " << multiply(numOne, numTwo) << endl;
}
else if (options == 4){
cout << "Enter your first number." << endl;
cin >> numOne;
cout << "Enter your second number." << endl;
cin >> numTwo;
cout << numOne << " / " << numTwo << " = " << divide(numOne, numTwo) << endl;
}
else {
cout << "Error, invalid option input." << endl;
}
cout << "Would you like to use this calculator again? (y/n)" << endl;
cin >> tryAgain;
}while (tryAgain == 'y');
cout << "Thank you for using my basic calculator!" << endl;
return 0;
}
`
One way would be to use exception handling, but as a newbie you're probably far from learning that.
Instead use the cin.fail() which returns 1 after a bad or unexpected input. Note that you need to clear the "bad" status using cin.clear().
A simple way would be to implement a function:
int GetNumber ()
{
int n;
cin >> n;
while (cin.fail())
{
cin.clear();
cin.ignore();
cout << "Not a valid number. Please reenter: ";
cin >> n;
}
return n;
}
Now in your main function wherever you are taking input, just call GetNumber and store the returned value in your variable. For example, instead of cin >> numOne;, do numOne = GetNumber();
When you input to cin, it is expecting a specific type, such as an integer. If it receives something that it does not expect, such as a letter, it sets a bad flag.
You can usually catch that by looking for fail, and if you find it, flush your input as well as the bad bit (using clear), and try again.
Read a whole line of text first, then convert the line of text to a number and handle any errors in the string-to-number conversion.
Reading a whole line of text from std::cin is done with the std::getline function (not to be confused with the stream's member function):
std::string line;
std::getline(std::cin, line);
if (!std::cin) {
// some catastrophic failure
}
String-to-number conversion is done with std::istringstream (pre-C++11) or with std::stoi (C++11). Here is the pre-C++11 version:
std::istringstream is(line);
int number = 0;
is >> number;
if (!is) {
// line is not a number, e.g. "abc" or "abc123", or the number is too big
// to fit in an int, e.g. "11111111111111111111111111111111111"
} else if (!is.eof()) {
// line is a number, but ends with a non-number, e.g. "123abc",
// whether that's an error depends on your requirements
} else {
// number is OK
}
And here the C++11 version:
try {
std::cout << std::stoi(line) << "\n";
} catch (std::exception const &exc) {
// line is not a number, e.g. "abc" or "abc123", or the number is too big
// to fit in an int, e.g. "11111111111111111111111111111111111"
std::cout << exc.what() << "\n";
}

Conditionally Breaking A Long Sequence Of Inputs?

I have a personal project I've been working on. To work, it needs to accept a lot of data (relatively) from the user, in the form of four different kinds of data for 12 users. As such, I have quite a lengthy sequence of statements similar to this:
cout << '\n' << "Monster A's name is: ";
cin >> nameA;
cout << '\n' << "Monster A rolled: ";
cin >> rollM_A;
cout << '\n' << "Monster A's Dex is: ";
cin >> DexA;
cout << '\n' << "Monster A's Mod is: ";
cin >> ModA;
cout << '\n' << "Monster A's Level is: ";
cin >> LvlA;
etc.
Occasionally, however, there might only be a need to input data for less than 12 monsters, say, 5-6 or even 1-2. I'd like to be able to use a command to skip the input section to the rest of the code based on something like a keystroke. i.e. If the user has put in data for 5 monsters, and that's all they require, they could hit the backslash to skip the rest of the input sequence.
Does what I'm talking about make any sense/is there an STL command to do what I'm looking for? Currently, this process isn't looped, but would exiting it be easier if it was inside a loop? I did have a thought of trying something like this:
while(cin.get() != '\') {
cout << '\n' << "Monster A's name is: ";
cin >> nameA;
//etc...
}
EDIT: The above attempt builds, but upon entering the desired keystroke, it quickly and endlessly prints the user prompts without accepting data. Any advice? All I want is for it to break and move on. Can I use a switch statement effectively?
Thanks!
That could work. You can also use EOF, which is more general, than '\'. Then when you are done, hit Ctrl-D to send the EOF, and you are done. This takes care of the situation when some player enters '\' as the Monster's name.
I just tested this set of code and it seems to work how you would like. Of course you will have to modify it to fit your original application.
std::string in;
while (true) {
std::cout << "Enter a name\n";
std::cin >> in;
if (in == "#")
break;
std::cout << "\nMonster A's name is: " << in << "\n";
}
In order to incorporate the limit of the number of monsters, rather than having the true parameter passed into the while loop, simply add a counter to how many monsters are created and break on that condition:
int num_monsters = 0;
while (num_monsters <= 12) {
...
num_monsters++;
}
Hope this helps.
You can check if the name is \, it is not user friendly but it works.
string name;
while (name != "\\") {
cout << '\n' << "Monster A's name is: ";
cin >> name;
cout << "Received " << name << '\n';
if (name != "\\") {
// do something with name ...
}
}
If the loop still loops endlessly, refer to How do I flush the cin buffer? and try clearing stdin buffer.
[edit] I fixed an error in the loop
Here's something I wrote.
struct Monster {
string name;
bool roll;
float dex;
float mod;
float level;
Monster(void) :
name(),
roll(false),
dex(0),
mod(0),
level(0) { }
};
bool getMonsterInformationFromStdin(int index, Monster& monster) {
string end_char = "\\";
string name, roll, dex, mod, level;
cout << '\n' << "Monster " << index << "'s name is: ";
cin >> name;
if (name.compare(end_char) == 0) return false;
monster.name = name;
cout << '\n' << "Monster " << index << " rolled: ";
cin >> roll;
if (roll.compare(end_char) == 0) return false;
monster.roll = (roll[0] == 'y' || roll[0] == 'Y') ? true : false;
cout << '\n' << "Monster " << index << "'s Dex is: ";
cin >> dex;
if (dex.compare(end_char) == 0) return false;
monster.dex = atof(dex.c_str());
cout << '\n' << "Monster " << index << "'s Mod is: ";
cin >> mod;
if (mod.compare(end_char) == 0) return false;
monster.mod = atof(mod.c_str());
cout << '\n' << "Monster " << index << "'s Level is: ";
cin >> level;
if (level.compare(end_char) == 0) return false;
monster.level = atof(level.c_str());
return true;
}
int main(int argc, char** argv) {
int max_monsters = 10;
for (int i = 0; i < max_monsters; i++) {
Monster m;
if( !getMonsterInformationFromStdin(i, m) ) break;
string roll = m.roll ? "rolled" : "didn't roll";
cout << m.name << " " << roll << " dex: " << m.dex << " mod: " << m.mod << " level: " << m.level << endl;
}
return 0;
}
I think this is problem can be solved by using a sentinel Monster name, as u can see below.
const string SentinelName = "%^&";
while(true)
{
cout << '\n' << "Monster A's name is(if u want to end, pls input %^&): ";
cin >> nameA;
if(strcmp(nameA, SentinelName.s_str())
break;
cout << '\n' << "Monster A rolled: ";
cin >> rollM_A;
cout << '\n' << "Monster A's Dex is: ";
cin >> DexA;
cout << '\n' << "Monster A's Mod is: ";
cin >> ModA;
cout << '\n' << "Monster A's Level is: ";
cin >> LvlA;
}
Hope this can solve ur problem. Besides, A little advice for ur code, u can encapsulate the attributes of the monster, such as the name, mode level, etc into a class and this will make ur code look fancier.

Check for non-numeric inputs in a C++ program

How do you check for non-numeric input using C++? I am using cin to read in a float value, and I want to check if non-numerical input is entered via stdin. I have tried to use scanf using the %d designator, but my output was corrupted. When using cin, I get the correct format, but when I enter, a string such as "dsffsw", I get an infinite loop.
The commented code was my attempt to capture the float, and type cast it as string, and check if it is a valid float, but the check always comes up false.
I have tried using other methods I have found on the message boards, but they want to use scanf in C and not cin in C++. How do you do this in C++? Or in C if it is not feasible.
while (!flag) {
cout << "Enter amount:" << endl;
cin >> amount;
cout << "BEGIN The amount you entered is: " << strtod(&end,&pend) << endl;
//if (!strtod(((const char *)&amount), NULL)) {
// cout << "This is not a float!" << endl;
// cout << "i = " << strtod(((const char *)&amount), NULL) << endl;
// //amount = 0.0;
//}
change = (int) ceil(amount * 100);
cout << "change = " << change << endl;
cout << "100s= " << change/100 << endl;
change %= 100;
cout << "25s= " << change/25 << endl;
change %= 25;
cout << "10s= " << change/10 << endl;
change %= 10;
cout << "5s= " << change/5 << endl;
change %= 5;
cout << "1s= " << change << endl;
cout << "END The amount you entered is: " << amount << endl;
}
return 0;
}
int amount;
cout << "Enter amount:" << endl;
while(!(cin >> amount)) {
string garbage;
cin.clear();
getline(cin,garbage);
cout << "Invalid amount. "
<< "Enter Numeric value for amount:" << endl;
}
I think you task relates to the so called defensive programming, one of it`s ideas is to prevent situations like one you described (function expects one type and user enters another).
I offer you to judge whether input is correct using method that returns stream state , which is good(),
so I think it will look something like this:
int amount = 0;
while (cin.good()) {
cout << "Enter amount:" << endl;
cin >> amount;