C++ validation loop issues - c++

I'm pretty new to c++ and am really close to the solution, but I still need some help. My loop works correctly the first time. After that when I enter the car number, it seems to be grabbing some input somewhere and just executes the invalid color on the second pass. Obviously, I'm missing something, but I'm at a loss. Any help would be appreciated.
This is just a small snippet of my program, but there lays the problem:
while (count < 3)
{
cout << endl << "Enter car color: blue, red or green in lower case. ";
getline(cin, carColor[count]);
if (!(carColor[count] == "blue" || carColor[count] == "red" || carColor[count] == "green"))
{
cout << "That is an invalid color"
<< "The program will exit";
cin.clear();
cin.ignore();
return 0;
}
cout << endl << "Enter car number between 1 and 99: ";
cin >> carNumber[count]; // Enter car number
if (carNumber[count] >99 || carNumber[count] < 1)
{
cout << "That is not a correct number"
<< " The program will exit";
return 0;
}
cout << "car no is:" << carNumber[count] << "color: " << carColor[count];
++count;
// int lapCount{ 1 };
cout << endl;
}

The '\n' character after you press enter in cin >> carNumber[count]; probably still remains so after you execute the second pass of getline(cin, carColor[count]); you get an empty string. One solution is to do this:
char c;
cin >> carNumber[count];
cin >> c;
But better solution would be just to change:
getline(cin, carColor[count]);
to:
cin >> carColor[count];

Related

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");

Won't let me read in user input in after IF statement (homework)

I am having some issues with my simple code of creating a dvd & software list to import into a csv file.
I have the output working fine but for some reason my program is skipping my first part of the code. If I take out the IF statement, that bit of code works so I am not understanding why.
my output looks like this:
Would you like to add new media? Enter M for Movie or S for software: m
Enter the name of the Movie (20 Chararters or less)Name: Enter a rating for
your movie 1-5:
I am not getting any errors in my compiler (Visual Studio 2013) and it does not allow me to input a name and skips right to rating.
Any explanations or suggestions would be appreciated as I want to fix this before I move on to adding more.
here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
string typeM = "movie";
string typeS = "software";
char answer, mediainput;
int rating = 0;
string dir, type;
string moviename,softname;
do
{
cout << "Would you like to add new media? Enter M for Movie or S for software: ";
cin >> mediainput;
cout << endl;
if (mediainput == 'm' || mediainput == 'M')
{
cout << "Enter the name of the Movie (20 Chararters or less) \n Name: ";
getline(cin, moviename);
cout << endl;
cout << "Enter a rating for your movie " << moviename << " 1-5 ";
cin >> rating;
if (rating < 1 || rating > 5)
{
cout << "You must enter a number from 1 to 5. Enter a number rating: ";
cin >> rating;
cout << endl;
}
ofstream outdata("DVD_Software_inventory.csv", ios_base::app);
outdata << moviename << "," << typeM << "," << rating << "," << endl;
outdata.close();
}
if (mediainput == 's' || mediainput == 'S')
{
cout << "Enter the name of the software (20 Chararters or less) \n Software name: " << endl;
getline(cin, softname);
cout << "Enter the directory it is in \n Directory: ";
cin >> dir;
ofstream outdata("DVD_Software_inventory.csv", ios_base::app);
outdata << softname << "," << typeS << ",," << dir << "," << endl;
outdata.close();
}
cout << "\n\nWould you like to add more? Y/N ";
cin >> answer;
cout << endl;
if (answer == 'N' || answer == 'n')
{
cout << "** End of Program **" << endl;
break;
}
} while (answer == 'Y' || answer == 'y');
system("pause");
return(0);
}
The problem is that while your cin >> statement ignores "\n" (the newline character), the character is still in cin's buffer. getline(), however,
does not ignore the "\n" character.
The solution, therefore, is to explicitly tell cin to ignore the "\n" character:
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
getline(cin, moviename);
(credit to http://www.cplusplus.com/forum/beginner/24470/)

Order of While Loops

So, I am fairly new to C++, and I am basically just trying to figure out how I would make things more user-friendly.
I made a fairly basic "calculator" type of program just to mess around!
It uses a lot of while loops for verification to make sure that if they make a mistake, they can re-input the data they want.
I am wondering, once it "outputs" their number, and the program ends, how would I be able to basically just output and then give them the option to restart (from the beginning).
Not sure if I explained that very clearly, but I am fairly new so I have no clue how I would do this seeing on how it is being read top to bottom.
Code:
int a;
int b;
string c;
cout << "1. Addition" << endl << "2. Subtraction" << endl << "3. Multiplication" << endl << endl;
cin >> c;
cout << endl;
while (c != "1" && c != "2" && c != "3"){
cout << "1. Addition" << endl << "2. Subtraction" << endl << "3. Multiplication" << endl << endl;
cin >> c;
cout << endl;
}
while (c == "1"){
cout << "Number 1: ";
cin >> a;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 1: ";
cin >> a;
}
cout << "Number 2: ";
cin >> b;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 2: ";
cin >> b;
}
cout << endl << "Output: " << a + b;
c = "kevin123";
cin.get();
}
while (c == "2"){
cout << "Number 1: ";
cin >> a;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 1: ";
cin >> a;
}
cout << "Number 2: ";
cin >> b;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 2: ";
cin >> b;
}
cout << endl << "Output: " << a - b;
c = "kevin123";
cin.get();
}
while (c == "3"){
cout << "Number 1: ";
cin >> a;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 1: ";
cin >> a;
}
cout << "Number 2: ";
cin >> b;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 2: ";
cin >> b;
}
cout << endl << "Output: " << a * b;
c = "kevin123";
cin.get();
}
cin.get();
return 0;
I would say that your code need a bit of tidying up and refactoring. It repeats a lot of code, so you you should probably rearrange it to avoid that repetition, so for example:
cout << "Number 1: ";
cin >> a;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 1: ";
cin >> a;
}
cout << "Number 2: ";
cin >> b;
while (!cin) {
cout << endl;
cin.clear();
cin.ignore(256, '\n');
cout << "Number 2: ";
cin >> b;
}
occurs identical for alternatives 1, 2 and 3.
You could make that into a common section, and only do the final step of the math to produce the result in different pieces of code. This should be done with if (c == "1") ... etc, since you don't actually want to loop in this case (or use a switch, since you are never going to have both c=="1" and c=="2" at the same time, so a switch on c[0] would be fine...). This would get rid of the c = "kevin123"; which is just an ugly hack to fix the problem that you are looping, when you don't really want to repeat things.
All of your validation loops could also be written as
do { cout << "prompt"; cin >> input; } while(...)
instead of repeating the prompt and reading of input.
Once you have made those modifications, you should wrap the entire main body of your program in another while or do { ... } while(...) loop to repeat the main body.
You could also make use of functions to perform reduce repetitions in the code.
It is a very good practice to learn from early on in programming to "do not repeat yourself" - do not write code that is identical or nearly identical - break the code out into functions, move it around so it's not repeating. This pays off in the long term, since when you need to change something, there is only one or a few places to change, rather than lots!
What your are looking for is a conditional outer most loop. You have is while loop for all possible values. This code is something you can work with.
int a, b;
char c;
cout << "Welcome To Calculator" << endl;
cout << "Please Enter\n1.Addition\n2.Substraction\n3.Division\n4.Multiplication" << endl;
cout << "Enter 'q' for exit" << endl;
while(cin >> c) {
if (isdigit(c))
{
if (c == '1')
cout << "Looking for Addition" << endl;
else if (c == '2')
cout << "Looking for Substraction" << endl;
else if (c == '3')
cout << "Looking for Division" << endl;
else if (c == '4')
cout << "Looking for MUltiplication" << endl;
// Requesting new calculation.
cout << "Please Enter\n1.Addition\n2.Substraction\n3.Division\n4.Multiplication" << endl;
cout << "Enter 'q' for exit" << endl;
}
else
break;
}
cout << "Thankyou for using the calculator" << endl;
return 0;
#user3646954:
The problem with your code is not only about the repetition of code but also the algorithm.
while (c != "1" && c != "2" && c != "3") checks for right the option (1 | 2 | 3). After which you loop around the options while( c == '1 | 2 | 3'). The loop doesn't makes sense since the loop will always exit after the first calculation (c = "kevin123"; cin.get()). You are never restarting your calculator.
The code snippet above removes the repetition of code for all options. The operator is requested at the start while(cin >> c). After completing the calculation ìf .. else if .. else if .. we go back to the top. (check the code).

Code to get user input not executing/skipping in C++

In the below code, I'm running into an error when I try to get the user to input their name. My program just skips it over and goes right over to making the function calls without allowing the user to enter their name. Despite the error, my program is compiling. I'm not sure what's going wrong as I wrote that part based off other examples I found on here. Any suggestions?
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
char showMenu();
void getLottoPicks(int[]);
void genWinNums(int[]);
bool noDuplicates(int[]);
const int SIZE = 7;
int main()
{
int userTicket[SIZE] = {0};
int winningNums[SIZE] = {0};
char choice;
string name;
srand(time(NULL));
do
{
choice = showMenu();
if (choice == '1')
{
cout << "Please enter your name: " << endl;
getline(cin, name);
getLottoPicks(userTicket);
genWinNums(winningNums);
for (int i = 0; i < SIZE; i++)
cout << winningNums[i];
}
} while (choice != 'Q' && choice != 'q');
system("PAUSE");
return 0;
}
Added the code for showMenu:
char showMenu()
{
char choice;
cout << "LITTLETON CITY LOTTO MODEL:" << endl;
cout << "---------------------------" << endl;
cout << "1) Play Lotto" << endl;
cout << "Q) Quit Program" << endl;
cout << "Please make a selection: " << endl;
cin >> choice;
return choice;
}
And getLottoPicks (this part is very wrong and I'm still working on it):
void getLottoPicks(int numbers[])
{
cout << "Please enter your 7 lotto number picks between 1 and 40: " << endl;
for (int i = 0; i < SIZE; i++)
{
cout << "Selection #" << i + 1 << endl;
cin >> numbers[i];
if (numbers[i] < 1 || numbers[i] > 40)
{
cout << "Please choose a number between 1 and 40: " << endl;
cin >> numbers[i];
}
if (noDuplicates(numbers) == false)
{
do
{
cout << "You already picked this number. Please enter a different number: " << endl;
cin >> numbers[i];
noDuplicates(numbers);
} while (noDuplicates(numbers) == false);
}
}
}
After doing cin >> choice; inside char showMenu(), if a user inputs 1[ENTER], the char consumes 1 character from cin, and the newline stays inside the stream. Then, when the program gets to getline(cin, name);, it notices that there's still something inside cin, and reads it. It's a newline character, so getline gets it and returns. That's why the program is behaving the way it is.
In order to fix it - add cin.ignore(); inside char showMenu(), right after you read the input. cin.ignore() ignores the next character - in our case, the newline char.
And a word of advice - try not to mix getline with operator >>. They work in a slightly different way, and can get you into trouble! Or, at least remember to always ignore() after you get anything from std::cin. It may save you a lot of work.
This fixes the code:
char showMenu()
{
char choice;
cout << "LITTLETON CITY LOTTO MODEL:" << endl;
cout << "---------------------------" << endl;
cout << "1) Play Lotto" << endl;
cout << "Q) Quit Program" << endl;
cout << "Please make a selection: " << endl;
cin >> choice;
cin.ignore();
return choice;
}
from looking at code showMenu function has problem. and it's not returning asccii equivalent of '1' that is: 31 integer. try printing value returned by showmenu. you will get that
UPDATE:
It is because cin in delimited by ' '(whitespace) and getline by '\n' character, so when enter name and press enter cin in showmenu will consume whole string except '\n' from istream and that is read by getline. to see this when it ask for choice enter string like 1 myname (1 whitespace myname)and press ENTER will display name. now cin will read 1 in choice and myname in name by getline.

Unable to correctly both verify invalid input and accept correct range values with C++

I am an amateur practicing code in C++ and I cannot get my code to work correctly. I am hoping that someone can find my issue or point me in the correct direction.
I am simply trying to create a switch/case menu for users to select from. I would like them to not be able to enter any incorrect values as input. the only correct values are 1,2,3 or 4. If there are any lower, greater, or non-numeric values entered I would like them to be stuck in a loop until they enter a correct value.
My issue with my working error check is that when they actually enter the correct values in they are still stuck in the loop?! I have tried rearranging my code, but then the error blows up my program again.
Thank you for any advice, code input, etc. I have no idea why it is not working!!!
And on a related note. I was having issues getting my jgrasp download to work correctly for c++ so i downloaded a compiler called code::block. for some reason it cannot register the system("") commands?! any ideas or a better compiler would be appreciated. thanks. oh and here is my code for my first issue... after the code is where my switch/case menu begins. thank you for any help
int main()
{
string name;
int ans2, ans3, count = 0, extra, select = 1, arraycount = 0, choice;
bool flag = true;
cout << "Hello World" << endl;
cout << "Enter your name: ";
cin >> name;
cout << "Thank you for using this program " + name << endl;
while (select != 4)
{
cout << "MAIN MENU\n";
cout << "Please enter a corrisponding numeric for your selection.\n";
cout << "1. You are Michael...\n";
cout << "2. You are Tim\n";
cout << "3. You are someone else\n";
cout << "4. Program exit\n";
cout << "Enter your selection: ";
cin >> select;
do
{
while(!(cin >> select))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Try again: ";
}
cout << "You entered: " << select << endl;
if (select != 1 && select != 2 && select != 3 && select != 4)
{
flag = false;
cout << "Error. Please enter a valid selection.";
cout << "Enter your selection";
cin >> select;
}
else
flag = true;
}while(flag == false);
cout << "\n\nThank you for your choice\n";
//system("pause");
//system("cls");
this part of your code ,
if (select != 1 && select != 2 && select != 3 && select != 4)
{
flag = false;
cout << "Error. Please enter a valid selection.";
cout << "Enter your selection";
cin >> select;
}
this part may be the cause of your problem as you input the select once again here, but you don't modify the flag value. You could add the check to while(!(cin >> select)) as
while(!(cin >> select) || select > 4 || select < 1)