I'm having some trouble during a do-while loop on my code.
It's about an interface class that makes a validation about the values that are typed by the user. I'm using Visual Studio 2012.
int Interface::requestOption(){
int option; //El problema está aquí
do{
cout<<"--------------------------------"<<endl;
cout<<"Type an option...";
cin>>option;
if(option<1 || option>8){
cout<<"Invalid value, type again "<<endl;
Sleep(2000);
system("cls");
menu();
}
}while(!(option>0 && option<9));
return option;
}
If I use the method for the first time, it returns the value that I actually typed. But when I call it again, while I debug, I notice that the value of option is -893453, and also, it doesn't allow me to type another number (cin >> option is not working).
The method is being called to interact within the next method:
void Control::studentsControl(){
int op;
do{
system("cls");
interEst->menu();
op = interEst->requestOption();
Lista<Students>* students= NULL;
students = U->getStudents();
switch(op){
//Eight options
//The 8th option is to return to the previous menu.
}while(op != 8);
}
Call std::cin.clear() after each iteration before enter new value.
!(option>0 && option<9) is True for -893453 !(False && True) == !False == True. why not use (option<1 || option>8) like in the if statement?
Related
I was writing a program inspired by one of my favorite books Diary of a wimpy kid. You play as Greg's dad and you have 3 options with what to do with him. When i ran the program I first selected the first option which printed the first one. I tried it again with the third option as well with the same result.
#include <iostream>
using namespace std;
void greg(int choice){
cout<<"Option 1: Scold."<<endl;
cout<<"Option 2: Take away games."<<endl;
cout<<"Option 3: kill "<<endl;
cin>>choice;
//Options on what to do with greg and getting user input.
if(choice = '1'){
cout<<"You told Greg he sucks. Responds with:"<<endl;
cout<<"Ok.."<<endl;
} else if(choice = '2'){
cout<<"You storm into Greg's room while Greg keeps asking you why."<<endl;
cout<<"Once you are insde and grab his game."<<endl;
}else if(choice = '3'){
cout<<"you killed greg."<<endl;
cout<<"A white bang then proceeds to happen."<<endl;
cout<<"You killed the main character. You no longer exist."<<endl;
}else{
cout<<"no"<<endl;
}
}
//All above is what will happen if you pick a choice.
int main()
{
cout<<"There once was a guy named Frank."<<endl;
cout<<"You talk to greg."<<endl;
cout<<"Yeah dad?"<<endl;
greg(3);
return 0;
}
you have to use a double = because you want to compare the values in the if statement. You dont want to set the left variable equal to the right value.
2.because youre passing a int value into the function, the program will not return true because a int is not equal to a string. So you dont have to use these '' around the number.
In conclusion you have to change this:
...
if(choice == 1){
//your code
}
else if(choice == 2){
//your code
}
else if(choice == 3){
//your code
}
...
#include"std_lib_facilities.h"
int main()
{
int i = 0;
int len_password;
cout<<"How Long Should Be Your Password?\n";
while(i == 0){
cin>>len_password;
if(!cin && len_password > 15){
cout<<"Please enter an appropriate value:\n";
}
else{
break;
cout<<"success!";
}
}
}
I want this code to print success when the loop breaks...and the loop will only break if the condition in if statement is satisfied....but even after typing the right input the loop is not breaking and also when i enter wrong input it is not allowing me to input once again...
If you checking it's less then 15 then print should be before the break and you don't need the !cin
You need to print "success" before breaking out of the loop. Also, your check for !cin doesn't make sense.
Instead, you could check if the cin operation failed, and if so, you can clear the stream to take additional input:
while(!(std::cin >> len_password) || len_password > 15)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Please enter an appropriate value:\n";
}
cout << "success";
The loop will keep executing until the user enters an appropriate value, and then "success" is printed outside the loop. This avoids any break statements within the loop.
I'm trying to validate input for a quit/return question in my program so the user is forced to enter either 'r' or 'q'.
I have managed to get it almost working. The problem is if the user enters 'r' or 'q' at the beginning followed by random letters then the program accepts that input. Any ideas on how to get the program to allow only a single 'r' or 'q' ?
void exit()
{
char choice;
bool badInput;
do
{
cout << "Press 'r' to return to the menu\nPress 'q' to quit the program\n\n" << endl;
cin >> choice;
badInput = cin.fail();
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} while (badInput == true && choice == 'r' && choice == 'q' && (cin.peek() == EOF));
if (choice == 'q')
{
system("CLS");
cout << "Bye!\n";
system("PAUSE");
}
else if (choice == 'r')
{
system("CLS");
main();
}
else
{
exit();
}
}
You've got a very strange way of approaching this problem that's got a lot of issues. In particular, creating a function called exit() is problematic since that's a core function, and calling it recursively to try and get input is likewise not a good plan. You already have a loop, you just need to use it more effectively.
Likewise, main() is called automatically and you should never have reason to call it manually.
Here's a first pass rewrite:
void getInput()
{
char choice;
while (true)
{
cout << "Press 'r' to return to the menu\nPress 'q' to quit the program\n\n" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin >> choice;
switch (choice)
{
case 'q':
system("CLS");
cout << "Bye!\n";
system("PAUSE");
exit(0);
break;
case 'r':
system("CLS");
doMain();
break;
}
}
}
This obviously needs more work, but at least should theoretically function. In your original code you're demanding that the input value be simultaneously two different things which is an impossibility, that code will never work.
I'd also encourage you to stop doing things like system("CLS") and system("PAUSE") and instead do something in C++ natively. That's not portable code and it's terribly clunky as it depends on commands from 1980s DOS.
Handling the input
Most implementation use a buffered cin, so that input will only be returned once the user press enter. If this is not acceptable to you, you'll have to use OS-dependent functions.
If it's ok for you, then if you read a char, only the first one will be handed over: the remaining chars until the enter will wait for subsequent reads. Therefore, instead of reading a single char, I propose you to read a full line into a string:
void want_exit()
{
const string message="Press 'r' to return to the menu\nPress 'q' to quit the program\n";
string line;
cout << message << endl;
while (getline(cin, line) && line.length()!=1
&& tolower(line[0])!='y' && tolower(line[0])!='n')
{
cout << "Invalid input" <<endl << message <<endl;
line.resize(0);
}
Now line contains either a single valid char, or it is empty (in case of premature eof, meaning, that there was an input redirection and that there will anyway be no more input).
Processing the input
You can't call recursively main(): you should instead return from the function, and organize the calling function so to continue the process
if (line.empty() || tolower(line[0])!='y' ) {
system("CLS"); // This is non portable
cout << "Bye!\nPress enter...";
cin.getch(); // as good as system("PAUSE");
std::exit(0); // be aware of the naming issue !
}
return;
}
The calling function (main() ?) would then use it in a loop:
while (...) {
...
if (...)
want_exit();
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm trying to make a program that asks the user whether they would like to continue to the next calculation. For some reasons whenever I enter y or Y, the program ends. However, if I use only one condition inside the if statement(without '||'sign), the code works fine. I just want to make sure that the user can enter both upper and lower case.
What's wrong with the code? Is there a better way to do this?
int main()
{
char choice;
while(true)
{
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice == 'Y'|| choice =='y'){
return true;
}else if(choice =='N'||choice =='n'){
return false;
}
}
return 0;
}
The return statement ends a function, in this case, this is the main, so it ends your program, whatever value you're returning.
If you only want to get out of your loop you have two solutions:
Use a boolean:
int main()
{
char choice;
bool run = true; //#stefaanv
while(run)
{
// Make your calculation
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N'||choice =='n'){
run = false;
}
}
return 0;
}
Use break to exit your loop:
int main()
{
char choice;
while(true)
{
// Make your calculation
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N'||choice =='n'){
break;
}
}
return 0;
}
But both these solution will consider any character entered exept N/n as "continue", if you want to avoid this:
int main()
{
char choice;
bool run = true;
while(run)
{
// Make your calculation
do{
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
choice = tolower(choice);//Put your letter to its lower case
}while (choice != 'n' && choice != 'y')
if(choice =='n'){
run = false;
}
}
return 0;
}
For some reasons whenever I enter y or Y, the program ends
The return statement is used to return control(and sometimes an optional value), to a functions caller. When return is used inside the called function, the function is terminated. From cppreference.com:
[return] terminates [the] current function and returns [a] specified value to the caller function.
(emphasis mine)
You may be under the impression that the statement return true inside your while-loop is returning the Boolean value of true to your while condition. It is not.
If your end goal is to create a yes/no style program that ends when the user enters "No/no", then you can to make use of the continue and break statements, or use a do/while loop.
Using continue and break
The continue statement is used to immediately skip to the next iteration of a loop, for or while, terminating the current iteration. From cppreference.com:
Causes the remaining portion of the enclosing for, range-for, while or do-while loop body to be skipped.
Used when it is otherwise awkward to ignore the remaining portion of the loop using conditional statements.
(emphasis mine)
The break statement is somewhat similar to continue, but instead of breaking the current iteration and skipping to the next one, it immediately breaks the entire program out of the while loop returning control to the outer-scope. From cppreference.com:
Causes the enclosing for, range-for, while or do-while loop or switch statement to terminate.
Used when it is otherwise awkward to terminate the loop using the condition expression and conditional statements.
(emphasis mine)
After examining the information above, you can modify your program to make use of continue and break, instead of return:
#include <iostream>
using namespace std; // This is for demonstration purposes ONLY
// never use this statement in your actual program. prefix cout and
// cin with std::
int main()
{
char choice;
while(true)
{
cout<<"Would you like to perform other calculations?(Y/N)"<<endl;
cin >> choice;
if(choice == 'Y'|| choice =='y'){
continue; // instead of returning, skip to the next iteration
// and ask again
}else if(choice =='N'||choice =='n'){
break; // return could be used here to break the while loop and
// terminate the program. But be explicit and use a statement specifically
// made for breaking out of loops
}
}
return 0;
}
Using a do/while loop
While the method above would work, I recommend using my second option-- a do/while loop. The do/while has the advantage o being shorter, and not having to make use of any kind of major control flow. From cppreference:
Executes a statement repeatedly, until the value of expression becomes false. The test takes place after each iteration.
If needed you could even add error checking to validate a users input:
#include <iostream>
using namespace std; // This is for demonstration purposes ONLY
// never use this statement in your actual program. prefix cout and
// cin with std::
int main()
{
char choice;
do { // do everything in the do block while...
cout <<"Would you like to perform other calculations?(Y/N)"<< endl;
cin >> choice;
if (choice != 'Y' and choice != 'y' and choice != 'N' and choice != 'n') // if needed add input
cout << choice << " is not a valid option. Try agian" << endl; // validation
} while (choice !='N' && choice !='n'); // the user input does not equal 'N'andr 'n'
return 0;
}
Output
Would you like to perform other calculations?(Y/N)
y
Would you like to perform other calculations?(Y/N)
Y
Would you like to perform other calculations?(Y/N)
n
References and Resources
cppreference.com
cplusplus.com
I just wrote some code and it works like a charm using "goto".
The code also included data validation as well. Many thanks to #Treycos.
int main()
{
char choice ='Y';
bool valid = true;
//some calculation
here:
int x =1+1;
cout<<x<<endl;
while(valid){
cout<<"Would you like to perform other calculation?(Y/N)"<<endl;
cin >> choice;
if(choice =='N' || choice =='n'){
break;
}
if(choice =='Y'||choice =='y'){
goto here;
}
else if(choice != 'N'&& choice != 'n'&&choice != 'Y'&&choice != 'y'){
cout<<"Invalid input."<<endl;
valid = true;
}
}
return 0;
}
Output:
2
Would you like to perform other calculation?(Y/N)
y
2
Would you like to perform other calculation?(Y/N)
Y
2
Would you like to perform other calculation?(Y/N)
$
Invalid input.
Would you like to perform other calculation?(Y/N)
n
Process returned 0 (0x0)
For uppercase n:
2
Would you like to perform other calculation?(Y/N)
N
Process returned 0 (0x0)
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 7 years ago.
Improve this question
I want to loop the whole codes If I press Y on "next customer"? and to reset the program just like the first try. Just type 0101 and 0307 on itemcode i put only some of my codes. define gotoxy is running only do while on "next customer " I think is the error?
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#define g gotoxy
main()
{
char back_, back;
float change, p0101 = 25.5, p0307=11,subtotal=0,total=0;
int y=9, quantity, itemcode, cash,discount;
clrscr();
do{
do{
g(1,8);
cout<<"Itemcode";
g(15,8);
cout<<"Quantity";
g(41,8);
cout<<"Price";
g(51,8);
cout<<"Subtotal";
g(62,8);
cout<<"Total";
g(1,y);
cin>>itemcode;
g(15,y);
cin>>quantity;
{
g(25,y);
if (itemcode == 0101){
cout<<"Yogurt(12 oz)";
subtotal = quantity * p0101;
}
else if (itemcode == 0307){
cout<<"Pumpkin (1000g)";
subtotal = quantity * p0307;
}
}
{
g(41,y);
if(itemcode == 0101){
cout<<"25.50";
}
else if (itemcode == 0307){
cout<<"79.75";
}
}
g(51,y);
cout<<subtotal;
total=total+subtotal;
g(62,y);
cout<<total;
subtotal=0;
g(72,8);
cout<<"Add item?";
g(72,y);
cin>>back;
y++;
if(back=='n'||back=='N'){
{
g(1,y+2);
cout<<"CASH: ";
cin>>cash;
}
if(cash>total){
{
g(1,y+3);
cout<<"[R]-REGULAR\t[D] - WITH DISCOUNT :";
}
cin>>discount;
g(1,y+4);
if(discount=='d'||discount=='D'){
(change=cash-(.8*total));
cout<<"Change: "<<change;
}
else{
change=cash-total;
cout<<"Change: "<<change;
}
}
else if(cash<total){
cout<<"Insufficient amount";
}
{
g(18,y+8);
cout<<"EXCHANGE OF ITEM TO ANOTHER TYPE AND SIZE IS ALLOWED,";
}
{
g(18,y+9);
cout<<"SUBJECT TO STANDARD PROVISIONS AND PRODUCT WARRANTY";
}
{
g(18,y+10);
cout<<" PLEASE PRESENT THIS RECEIPT";
}
{
g(15,y+12);
cout<<"Next Customer?";
cin>>back;
}
}
} while(back_=='Y'||back_=='y');
} while(back=='Y'||back=='y');
enter code here
getchar();
return 0;
}
You have some mistakes in programs.
take discount type int but use as a char
When your takes a integer value and after that takes a char, then between these, need to use getchar() because at the time of getting the integer, you press enter, so need to read it.
When you read a char, check that did you take a input before it, if takes, then read the newline character by getchar()
Check the code
#include<iostream>
#include<conio.h>
#include<stdio.h>
using namespace std;
int main()
{
char newCustomer, addItem,discount;
float change, p0101 = 25.5, p0307=11,subtotal=0,total=0;
int y=9, quantity, itemcode, cash;
do{
subtotal=0,total=0;
do{
cout<<"Itemcode: ";
cin>>itemcode;
cout<<"Quantity: ";
cin>>quantity;
{
if (itemcode == 101){cout<<"Yogurt(12 oz)";
subtotal = quantity * p0101;
}else if (itemcode == 307){cout<<"Pumpkin (1000g)";
subtotal = quantity * p0307;
}}
{
cout<<"Price: ";
if(itemcode == 101){
cout<<"25.50\n";
}else if (itemcode == 307){
cout<<"79.75\n";
}}
cout<<"Subtotal: ";
cout<<subtotal<<"\n";
total=total+subtotal;
cout<<"Total: ";
cout<<total<<"\n";
subtotal=0;
cout<<"Add item?";
cin>>addItem;
getchar();
if(addItem=='n'||addItem=='N'){
{
cout<<"CASH: ";
cin>>cash;}
getchar();
if(cash>total){
{
cout<<"[R]-REGULAR\t[D] - WITH DISCOUNT :";}
cin>>discount;
char c = getchar();
if(discount=='d'||discount=='D'){(change=cash-(.8*total));
cout<<"Change: "<<change<<"\n";}
else{change=cash-total;cout<<"Change: "<<change;}
}
else if(cash<total)
{cout<<"Insufficient amount";}
{
cout<<"EXCHANGE OF ITEM TO ANOTHER TYPE AND SIZE IS ALLOWED,";
}
{
cout<<"SUBJECT TO STANDARD PROVISIONS AND PRODUCT WARRANTY";}
{
cout<<" PLEASE PRESENT THIS RECEIPT\n";} {
cout<<"Next Customer?";cin>>newCustomer;char c = getchar();}
}
}while(addItem=='Y'||addItem=='y');
}while(newCustomer=='Y'||newCustomer=='y');
return 0;
}
I cannot see where you input into back_ but you have cin>>back; twice. Could this be your error? Your control structures are hard to follow.
You have, essentially,
do {
do {
// input some stuff for an item
cout<<"Add item?";
cin>>back;
if(back == 'n' || back == 'N')
{
// some code to finalize the transaction
cout<<"Next Customer?";
cin>>back;
}
} while (back_=='y' || back_=='Y')
} while (back=='y' || back == 'Y')
You defined back_ but never initialized it or used it in your code so when while (back_=='y' || back_=='Y') comes along, even when you press 'y', the loop never loops.
If you were to change the code to:
do {
do {
// input some stuff for an item
cout<<"Add item?";
cin>>back;
if(back == 'n' || back == 'N')
{
// some code to finalize the transaction
cout<<"Next Customer?";
cin>>back_;
}
} while (back_=='y' || back_=='Y')
} while (back=='y' || back == 'Y')
The program would certainly loop again if you pressed 'y' but you would get some interesting behavior when you pressed 'n' for "Add item?" and 'y' for "Next Customer?". I predict the program will close prematurely. Better to have:
char new_customer, add_item
do {
//---This is the outer loop---//
do {
//---This is the inner loop---//
// input some stuff for an item
cout<<"Add another item?";
cin>>add_item;
if(add_item == 'n' || add_item == 'N')
{
// some code to finalize the transaction
cout<<"Next Customer?";
cin>>new_customer;
}
//---End of the inner loop---//
} while (add_item=='y' || add_item=='Y')
//---End of the outer loop---//
} while (new_customer=='y' || new_customer=='Y')
This way the inner loop breaks when you press 'n' at "Add Item?" and the outer loop breaks when you press 'n' at "Next Customer?", effectively ending the program. Pressing 'y' at either will continue their respective loops.
Other odd behavior can come from
Pressing anything other than 'y' or 'n' at decision points
Inputting anything other than numbers into variables that are used to calculate prices and the such
Not formatting your output into the price fields with $ or having two decimal places for money
The first two can be fixed by reading everything in as strings and then parsing it out character by character to check for valid input and then converting the appropriate strings into a numbers using built-in C++ functions. The last one can be fixed with a little fancy calculations on the data with the % (modulus) operator to see if the values end with a zero or not. Just some ideas.
Looks like it mostly works, except for that one major error.