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).
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
Hello I am trying to build a project but the case '2' is not working.
struct student
{
string fname;//for student first name
string lname;//for student last name
string id;//for Registration No number
string course;//for class info
}studentData;//Variable of student type
struct teacher
{
string fname;//first name of teacher
string lname;//last name of teacher
string id;//Bool Group
string course;//Number of serves in School
}teach;//Variable of teacher type
int main()
{
int i = 0, j;//for processing usage
char choice;//for getting choice
string find;//for sorting
string srch;
while (1)//outer loop
{
system("cls");//Clear screen
//Level 1-Display process
cout << "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\";
cout << "\n\n\t\t\tSCHOOL MANAGEMENT PROGRAM\n\n";
cout << "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\";
cout << "\n\n\t\t\tMAIN SCREEN\n\n";
cout << "Enter your choice: " << endl;
cout << "1.Students information" << endl;
cout << "2.Teacher information" << endl;
cout << "3. Course information " << endl;
cout << "4. Display Strudent information " << endl;
cout << "5. Display Teacher Information " << endl;
cout << "6. Display Course Information n" << endl;
cout << "7.Exit program" << endl;
cin >> choice;
system("cls");//Clear screen
switch (choice)//First switch
{
case '1': //Student
{
{ ofstream f1("student.txt", ios::app);
for (i = 0; choice != 'n'; i++)
{
if ((choice == 'y') || (choice == 'Y') || (choice == '1'))
{
cout << "Enter First name: ";
cin >> studentData.fname;
cout << "Enter Last name: ";
cin >> studentData.lname;
cout << "Enter Registration number: ";
cin >> studentData.id;
cout << "Enter class: ";
cin >> studentData.course;
f1 << studentData.fname << endl << studentData.lname << endl << studentData.id << endl << studentData.course << endl;
cout << "Do you want to enter data: ";
cout << "Press Y for Continue and N to Finish: ";
cin >> choice;
}
}
f1.close();
}
continue;//control back to inner loop -1
continue;//Control pass to 1st loop
}
case '2'://Teachers biodata
{
{ ofstream t1("teacher.txt", ios::app);
for (i = 0; choice != 'n'; i++)
{
if ((choice == 'y') || (choice == 'Y') || (choice == '1'))
{
cout << "Enter First name: ";
cin >> teach.fname;
cout << "Enter Last name: ";
cin >> teach.lname;
cout << "Enter Registration number: ";
cin >> teach.id;
cout << "Enter class: ";
cin >> teach.course;
t1 << teach.fname << endl << teach.lname << endl << teach.id << endl << teach.course << endl;
cout << "Do you want to enter data: ";
cout << "Press Y for Continue and N to Finish: ";
cin >> choice;
}
}
t1.close();
continue;//control back to inner loop -1
}
continue;//Control pass to 1st loop
}
case '3':
{
{ ifstream f2("student.txt");
cout << "Enter First name to be displayed: ";
cin >> find;
cout << endl;
int notFound = 0;
for (j = 0; (j < i) || (!f2.eof()); j++)
{
getline(f2, studentData.fname);
if (studentData.fname == find)
{
notFound = 1;
cout << "First Name: " << studentData.fname << endl;
cout << "Last Name: " << studentData.lname << endl;
getline(f2, studentData.id);
cout << "Registration No number: " << studentData.id << endl;
getline(f2, studentData.course);
cout << "Class: " << studentData.course << endl << endl;
}
}
if (notFound == 0) {
cout << "No Record Found" << endl;
}
f2.close();
cout << "Press any key two times to proceed";
_getch();//To hold data on screen
_getch();//To hold data on screen
}
continue;//control back to inner loop -1
}
case '4':
{
{ ifstream t2("teacher.txt");
cout << "Enter First name to be displayed: ";
cin >> find;
cout << endl;
int notFound = 0;
for (j = 0; (j < i) || (!t2.eof()); j++)
{
getline(t2, studentData.fname);
if (studentData.fname == find)
{
notFound = 1;
cout << "First Name: " << studentData.fname << endl;
cout << "Last Name: " << studentData.lname << endl;
getline(t2, teach.id);
cout << "Registration No number: " << studentData.id << endl;
getline(t2, teach.course);
cout << "Class: " << studentData.course << endl << endl;
}
}
if (notFound == 0) {
cout << "No Record Found" << endl;
}
t2.close();
cout << "Press any key two times to proceed";
_getch();//To hold data on screen
_getch();//To hold data on screen
}
continue;//control back to inner loop -1
}
case '5':
{}
case '6':
{}
case '7':
{
break;//outer case 3
}//outer case 3
break;//outer loop
}
}
}
inside your switch statement, inside the case where you are checking if "choice" is '2 (case '2'://Teachers biodata), you have yet another if statement which checks if "choice" is '1', but at that point "choice" will be '2'.
if ((choice == 'y') || (choice == 'Y') || (choice == '1'))
becomes
if ((choice == 'y') || (choice == 'Y') || (choice == '2'))
I already posted this question, but none of the responses were correct once I implemented the suggestions I was given. Here is what I need to happen.
Would you like to process all the records in the file? (y/n) w
Error - Please enter either y or n.
Would you like to process all the records in the file? (y/n) n
Enter number of records to process: two
XXXXXXXXXX Error-non numeric or negative value, try again
Enter number of records to process: -10
XXXXXXXXXX Error-non numeric or negative value, try again
Enter number of records to process: 0
XXXXXXXXXX Error-non numeric or negative value, try again
Enter number of records to process: 10
Maximum requested record count of 10 reached
Here is what I have. I don't know what I am doing wrong.
#include <iostream>
#include <fstream>
using namespace std;
int main(){
char a = 0; //User chooses Y or N
int ProcessAmount = 0; //Amount of times to process if not all
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
if (a == 'y')
{
cout << "Processed all records successfuly" << endl;
}
do
{
if (a == 'n')
{
cout << "Enter number of records to process: ";
cin >> ProcessAmount;
if (ProcessAmount <= 0 or cin.fail())
{
cout << "" << endl;
cout << "XXXXXXXXX Error-non numeric or negative value";
cout << "" << endl;
cin >> ProcessAmount;
}
else if (ProcessAmount >= 0 or (!(cin.fail())))
;
{
cout << "Maximum requested record count of " << ProcessAmount;
cout << " reached" << endl;
break;
}
}
else
(cin.fail());
{
cin.clear();
cin.ignore(40, '\n');
cout << "Please try again" << endl;
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
}
} while (a == 'n');
}
First of all or is something I didn't know worked in C++, but in my gcc compiler it works fine, so thank you for that, I still replaced it with || in my answer, though.
Apart from that there are some issues with the sequence of events in your do - while cycle, try the code below.
Live sample here
do {
if (a == 'y') {
cout << "Processed all records successfuly" << endl;
break;
}
if (a == 'n') {
cout << "Enter number of records to process: ";
cin >> ProcessAmount;
if (ProcessAmount <= 0 || cin.fail()) {
cout << "XXXXXXXXX Error-non numeric or negative value";
cout << "" << endl;
}
else {
cout << "Maximum requested record count of " << ProcessAmount;
cout << " reached" << endl;
break;
}
cin.clear();
cin.ignore(40, '\n');
continue;
}
cout << "Please try again" << endl;
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
} while (a != 'y');
First of all, the value of a must be validated, with something like:
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
//validating a
while (a != 'n' && a != 'y'){
cout << "Error - Please enter either y or n." << endl;
cout << "Would you like to process all the records in the file? "
<< "(y/n) ";
cin >> a;
}
//...do things if a='n'
//...do thing if a='y'
then you should stop worrying about a, then you can do things if a = n or if a = y
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
to some this might seem simple, but to me I can't really seem to figure out why this isn't working. I know I could just copy and paste every time inside the while loop to get the result I want, but I've been told that if you have to repeat something more than one time to write a function! My code will double print the number and even though someone would type 8 it will still go into the while loop. Hoping someone can explain why this is happening to me.
int main()
{
int option = selectionHelper();
cout << selectionHelper() << endl;
cout << endl;
if(option == 8)
{
cout << "Exiting program..." << endl;
cout << endl;
cin >> option;
}
while (option != 8)
{
if (option == 1){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else if(option == 2){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else if(option == 3){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else if(option == 4){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else if(option == 5){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else if(option == 6){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else if(option == 7){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else{
cout << "Invalid input... Please try again..." << endl;
cout << endl;
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}//end else if statement
}//end while loop
}//end function main
and now for my function:
int selectionHelper()
{
int option;
cout << "1. Initialize seating for new performance." << endl;
cout << "2. View seating chart." << endl;
cout << "3. Reserve seats." << endl;
cout << "4. Calculate tickets remaining in row." << endl;
cout << "5. Calculate tickets remaining in theater." << endl;
cout << "6. Calculate total tickets sold." << endl;
cout << "7. Calculate ticket sales." << endl;
cout << "8. Exit program." << endl;
cout << "Option: " << endl;
cin >> option;
return option;
}//end selectionHelper
Thank you for looking at my post!
This answer and others will tell you what code to write to fix your problem. If you should encounter similar problems in the future, try walking through your code with a debugger. (Experience helps too.) Regarding code redundancy: first, it's good that you used the selectionHelper() method. That shows you have good instincts. Here's what you can do further:
Look for lines of code that are the same or differ only by a variable.
Consider condensing them in the following ways:
Can you use a for-loop?
Can you put the code in a method (possibly abstracting out a variable?)
Can you use a broader conditional statement? (That's what you have going on here: if a number is 1, 2, 3, 4, 5, 6, or 7, it's also >0 and <7. That's why we have ranges.)
The program keeps going when they enter 8 because you ask them to input a number after they input 8! So your first chunk of code can be simpler:
int option = selectionHelper();
cout << option << endl <<endl; // <-- output option, don't call selectionHelper() here again, that's why you get double printing
if(option == 8)
{
cout << "Exiting program..." << endl;
cout << endl;
//cin >> option; // <-- don't input here again!
}
The key here to simplifying your code is to recognize that you only write different code in a few cases. So, here's your while loop:
while (option != 8)
{
if (option > 0 && option < 8){
cout << selectionHelper() << endl;
cout << endl;
cin >> option;
}else{
cout << "Invalid input... Please try again..." << ends << endl;
cout << selectionHelper() << endl << endl;
cin >> option;
}//end else if statement
}
You must modify your code in the following ways:
int option = selectionHelper();
cout << option << endl;
And also:
if(option == 8)
{
cout << "Exiting program..." << endl;
}
You can simplify your code down to (using partly the simplification made by cuniculus but also fixing the mistake in your own code of wrong using option):
#include <iostream>
using namespace std;
int selectionHelper()
{
int option;
cout << "1. Initialize seating for new performance." << endl;
cout << "2. View seating chart." << endl;
cout << "3. Reserve seats." << endl;
cout << "4. Calculate tickets remaining in row." << endl;
cout << "5. Calculate tickets remaining in theater." << endl;
cout << "6. Calculate total tickets sold." << endl;
cout << "7. Calculate ticket sales." << endl;
cout << "8. Exit program." << endl;
cout << "Option: " << endl;
cin >> option;
return option;
}//end selectionHelper
int main()
{
int option = selectionHelper();
while (option != 8)
{
if (option > 0 && option < 8){
option = selectionHelper();
}else{
cout << "Invalid input... Please try again..." << ends << endl;
option = selectionHelper();
}//end else if statement
}
cout << "Exiting program..." << endl;
return 0;
}//end function main
Your mistake was basically in calling selectionHelper too many times, when only once is needed to set the option variable. You have a similar thing going on in your whole if-else structure - but I'll leave it up to you to fix that if needed, the solution is the same.
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];
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";
}