I am making a program which consists of making a menu to register and delete products from a store, I am just designing the menu with a switch, everything works fine up to there, the problem is that when I enter something other than a number as data ( letter or symbol) the console goes crazy; all the text starts to blink and it won't let me do anything (as if it was in a loop) and I have to close it.
Is there any way to avoid this? So when I enter a letter or symbol, it automatically detects it as invalid and shows me the message without the console going crazy?
By the way, I use Visual Studio.
Thanks in advance :)
#include<iostream>
#include<locale.h>
using namespace std;
int main()
{
int opc;
cout << " WELCOME TO THE STORE \"Happy Shopping\" ";
cout << endl;
cout << "\n1.- Create Order.";
cout << "\n2.- Delate Order.";
cout << "\n3.- list of orders created.";
cout << "\n4.- Exit";
cout << endl;
cout << "\n¿what do you want to do?: "; cin >> opc;
switch (opc)
{
case 1:cout << "\nCreate Order"; break;
case 2:cout << "\nDelate Order"; break;
case 3: cout << "\nlist of orders created"; break;
case 4:exit(EXIT_SUCCESS);
default:
if ((opc != 1) && (opc != 2) && (opc != 3) && (opc != 4))
{
system("cls");
cout << "the option entered is not valid, try again";
return main();
}
}
}
Maybe don't return main?
switch (opc)
{
case 1:cout << "\nCreate Order"; break;
case 2:cout << "\nDelate Order"; break;
case 3: cout << "\nlist of orders created"; break;
case 4:exit(EXIT_SUCCESS);
default:
system("cls");
cout << "the option entered is not valid, try again";
}
If you make opc a string and take input as a string, you can manually check if the string is a number like so:
cin >> opc;
if (!isdigit(opc[0]) // since you're dealing with single-digit numbers, this should be fine
{
cout << "You didn't enter a number!\n";
// Any other error handling
}
isdigit is a function located in the cctype header file, so you should add #include <cctype> at the beginning of the file.
After this, you can convert opc to an integer with stoi():
int opnum = stoi(opc);
// opnum is now the number, write the rest of the code such that it uses opnum
As already said, you should not return main(). You may use a loop by testing your input for instance (surely one of the many solutions that may exist).
Also, you do not need the portion of code below :
// you do not need the if as you are already in the case !=1,2,3, or 4
if ((opc != 1) && (opc != 2) && (opc != 3) && (opc != 4))
I provided you with an attempt, taken from your code, that may help to improve your code.
There might still be some bugs but it is a good starting point
#include<iostream>
#include<locale.h>
int main()
{
int opc=0;
std::string input;
std::cout << " WELCOME TO THE STORE \"Happy Shopping\" ";
std::cout << std::endl;
// first display
std::cout << "\n1.- Create Order.";
std::cout << "\n2.- Delate Order.";
std::cout << "\n3.- list of orders created.";
std::cout << "\n4.- Exit";
std::cout << std::endl;
std::cout << "\n¿what do you want to do?: "; //cin >> opc;
std::cin >> input;
while ( input.length() > 0 )
{
// if we enter a string of more than length 1
try
{
opc = std::stoi( input );
}
catch (...)
{
// mainly if the converted argument is not a number =>std::invalid_argument
std::cout << "invalid value " << opc << std::endl;
}
std::cout << "you entered the value " << opc << std::endl;
switch (opc)
{
case 1:
std::cout << "\nCreate Order";
break;
case 2:
std::cout << "\nDelate Order";
break;
case 3:
std::cout << "\nlist of orders created";
break;
case 4:
exit(EXIT_SUCCESS);
default:
// you do not need the if as you are already in the case !=1,2,3, or 4
//if ((opc != 1) && (opc != 2) && (opc != 3) && (opc != 4))
//{
system("cls");
// if you type things other than
std::cout << "\n1.- Create Order.";
std::cout << "\n2.- Delate Order.";
std::cout << "\n3.- list of orders created.";
std::cout << "\n4.- Exit";
std::cout << std::endl;
std::cout << "\n¿what do you want to do?: "; //cin >> opc;
}
std::cin >> input;
}
}
Related
i am making a word guessing game in c++ (im new at programming btw) im just gonna ask how can i make the "already-answered" answers as wrong and cant get points from the same word again? here's my current code...
#include <iostream>
#include <string>
using namespace std;
int main()
{
int firstQPoint, secondQPoint, thirdQPoint, mane;
char yourChoice, levelChoice, goBack;
string yourFirstAnswer, yourSecondAnswer, yourThirdAnswer;
gameMenu:
cout << "\t GUESS THE WORD GAME";
cout << "\t\n\n MADE BY GROUP FIVE";
cout << "\t\t\n\n 1. PLAY | ENTER \"1\" TO PLAY ";
cout << "\t\t\n\n 2. QUIT | ENTER \"2\" TO QUIT ";
cout << "\t\t\n\n 3. RULES | ENTER \"3\" TO SEE THE RULES";
cout << "\t\t\n\n What Do You Want To Do : ";
cin >> yourChoice;
if (yourChoice == '1') {
cout << "\t GUESS THE WORD GAME";
cout << "\t\n\n MADE BY GROUP FIVE";
selectALevel:
cout << "\t\n\n OKAY, CHOOSE A LEVEL (1-3) : ";
cin >> levelChoice;
switch (levelChoice) {
case ('1'):
cout << "\t GUESS THE WORD GAME";
cout << "\t\n\n MADE BY GROUP FIVE";
cout << "\t\t\n\nGIVE 3 BODY PARTS THAT STARTS WITH LETTER \"T\"";
cout << "1 : ";
cin >> yourFirstAnswer;
if (yourFirstAnswer == "TOE", "TONGUE", "TOOTH") {
cout << "\n\n\t\tNICE, YOU GOT A POINT!";
firstQPoint = 1 + 0;
}
cout << "2 : ";
cin >> yourSecondAnswer;
if (yourSecondAnswer == "TOE", "TONGUE", "TOOTH") {
cout << "\n\n\t\tNICE, YOU GOT A POINT!";
secondQPoint = 1 + firstQPoint;
}
cout << "3 : ";
cin >> yourThirdAnswer;
if (yourThirdAnswer == "TOE", "TONGUE", "TOOTH") {
cout << "\n\n\t\tNICE, YOU GOT A POINT!";
thirdQPoint = 1 + secondQPoint;
}
break;
case ('2'):
break;
case ('3'):
break;
default:
goto selectALevel;
}
}
else if (yourChoice == '3') {
do {
cout << "\t GUESS THE WORD RULES";
cout << "\t\t\n\n1. ONLY USE UPPERCASE LETTERS";
cout << "\t\t\n\n1. ONLY USE SINGULAR WORDS";
cout << "\t\t\n\n ENTER \"1\" TO GO BACK : ";
cin >> goBack;
if (goBack == '1') {
goto gameMenu;
}
} while (goBack != '1');
}
else if (yourChoice == '2') {
cout << "\t\t\n\n Okay, Goodbye!";
}
return 0;
}
i tried the longer way, where i will manually code it like this
#include <iostream>
using namespace std;
int main()
{
int number, again;
cout << "give 2 number";
cin >> number;
cout << "again :";
cin >> again;
if (number == 1 && again == 2) {
cout << "correct";
else if (number == 2 && again == 1)
{
cout << "correct";
}
}
}
but it's very hard since im working with too many combinations! thanks in advance for answering!
Inside each switch case you can make a loop to repeat the question if the word is wrong.
At the beginning of the switch (before the loop) you can create an empty list where you will store every answer they give.
In the end you only need to make a function that goes through that same list and checks if a word is inside it or not.
Program should begin with asking , whether to restock or continue with the current stock. The case 1 ( restock ) works perfectly , however the second case , to continue with the previous stock , returns zeros always if any of the products is zeroed.
In the textfile I have:
Milk: 10
Eggs: 2
Water: 7
Burrito: 10
Bread: 12
exit
How can i fix that ?
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
#include<sstream>
using namespace std;
string productName[5] = { "Milk", "Eggs", "Water", "Burrito", "Bread" };
//int productAmount[5] = { 5,12,10,4,7};
int productAmount[5];
int productPick;
int defaultPick;
int productBuy;
fstream productFile; //we create file
void loadFromFile()
{
productFile.open("productsfile.txt", ios::in);
if (productFile.good() == false)
{
cout << "Unable to load the file. Try again later." << endl;
productFile.close();
exit(0);
}
else
{
ifstream productFile("productsfile.txt");
if (productFile.is_open())
{
cout << "How may I help you?" << endl;
string line;
while (getline(productFile, line))
{
// using printf() in all tests for consistency
cout << line.c_str() << endl;
}
productFile.close();
}
}
}
void saveToFile() //this function saves in the text file the data we've globally declared. It is used only if you want to declare new variables.
{
productFile.open("productsfile.txt", ios::out);
for (int i = 0; i < 5; i++)
{
productFile << i + 1 << ". " << productName[i] << ": " << productAmount[i] << endl;
}
productFile << "6. Exit" << endl;
productFile.close();
}
void askIfDefault()
{
cout << "Do you want to come back to default stock?" << endl;
cout << "1. Yes " << "2. No " << endl;
cin >> defaultPick;
switch (defaultPick)
{
case 1:
for (int i = 0;i < 5;i++)
{
productAmount[i] = 10;
}
saveToFile();
loadFromFile();
break;
case 2:
loadFromFile();
break;
default:
cout << "I don't understand." << endl;
exit(0);
break;
}
}
void productCheck()
{
if (productAmount[productPick - 1] <= 0 || productAmount[productPick - 1] < productBuy)
{
cout << "Unfortunately we have no more " << productName[productPick - 1] << " in stock. Please choose other product from the list below: " << endl;
productAmount[productPick - 1] = 0;
}
else
{
productAmount[productPick - 1] -= productBuy;
}
}
void listOfProducts()
{
cout << "How may I help you?" << endl;
for (int i = 0; i < 5; i++)
{
cout << i + 1 << ". " << productName[i] << ": " << productAmount[i] << endl;
}
cout << "6. Exit" << endl;
}
void order()
{
cin >> productPick;
switch (productPick)
{
case 1:
cout << "How many bottles?" << endl;
cin >> productBuy;
{
productCheck();
saveToFile();
}
break;
case 2:
cout << "How many cartons?" << endl;
cin >> productBuy;
{
productCheck();
saveToFile();
}
break;
case 3:
cout << "How many multi-packs?" << endl;
cin >> productBuy;
{
productCheck();
saveToFile();
}
break;
case 4:
cout << "How many portions?" << endl;
cin >> productBuy;
{
productCheck();
saveToFile();
}
break;
case 5:
cout << "How many batches?" << endl;
cin >> productBuy;
{
productCheck();
saveToFile();
}
break;
case 6:
cout << "See you soon!" << endl;
saveToFile();
system("pause");
break;
case 666:
cout << "You cannot use the secret magic spells here." << endl;
saveToFile();
exit(0);
break;
default:
cout << "Please pick the existing product: " << endl;
saveToFile();
order();
break;
}
}
int main()
{
askIfDefault();
order();
cout << endl;
while (true && productPick != 6)
{
listOfProducts();
order();
saveToFile();
cout << endl;
}
return 0;
}
Maybe unless declaring one global fsteam productFile, try to declare the it inside each of both functions that are using it: 'loadFromFile()' and 'saveToFile()' respectively. At the beginning of them. It should be fine then.
Let me make a few additional suggestions about your code - because it's a bit difficult to follow:
Choose function names which reflect what the function does - and don't do anything in a function which exceeds what its name indicates. For example, if you wrote a function called ask_whether_to_restock() - that function should ask the question, and perhaps even get the answer , but not actually restock even if the answer was "yes" - nor write anything to files. Even reading information from a file is a bit excessive.
If you need to do more in a function than its name suggests - write another function for the extra work, and yet another function which calls each of the first two and combines what they do. For example, determine_whether_to_restock() could call read_current_stock_state() which reads from a file, and also print_stock_state() and, say, get_user_restocking_choice().
Try to avoid global variables. Prefer passing each function those variables which it needs to use (or references/pointers to them if necessary).
Don't Repeat Yourself (DRI): Instead of your repetitive switch(produtPick) statement - try writing something using the following:
cout << "How many " << unit_name_plural[productPick] << "?" << endl;
with an additional array of strings with "bottles", "cans", "portions" etc.
I'm current writing a simple application that involve certain menu driven, such as Main Menu > Sub-menu > sub-sub-menu.. etc.
And I put input validation on all of them to prevent input error like,
while (option != '1' && option != '2' && option != '3' && option != '0')
{
//correction prompt
}
In one of my menu, when I enter its sub-menu, and return back to it. Any input that I attempt to enter will result the system went into my validation loop at least once, given the input is appropriate or not.
My Code:
void passengerRecord()
{
int again = 0;
char option;
do
{
system("CLS");
cout << "Please tell me what you want to do." << endl;
cout << "1. Add Passenger Record" << endl;
cout << "2. Edit Passenger Record" << endl;
cout << "3. Delete Passenger Record" << endl;
cout << "0. Back to System Module Menu" << endl;
cout << "Your choice: ";
cin.ignore();
if (again > 0)
cin.clear();
cin.get(option);
while (option != '1' && option != '2' && option != '3' && option != '0')
{
system("CLS");
cout << "Error Input! Please try again." << endl;
cout << "Please tell me what you want to do." << endl;
cout << "1. Add Passenger Record" << endl;
cout << "2. Edit Passenger Record" << endl;
cout << "3. Delete Passenger Record" << endl;
cout << "0. Back to System Module Menu" << endl;
cout << "Your choice: ";
cin.get(option);
}
switch (option)
{
case '1': passengerAddsa();break;
case '2': passengerEditsa();break;
case '3': passengerDeletesa();break;
case '0': cout << "Redirecting back to module menu...";
cin.ignore();break;
default: cout << "Exception error occurred!";
}
again++;
} while (option != '0');
}
As long as I've enter one of its sub-menu (add,edit,delete), and return to here (either the other function using cin.get() and proceed to return;, or end of function), the next input I enter for this menu will goes into validation loop at least once.
This situation only occurred at second time ++ access to this menu, first time access has no problem
Method that I've tried:
1.) cin.ignore(), its useless and just required me to input more line.
2.) cin.clear(), I see no difference. Probably it has nothing to do with cin buffer
3.) Only run 1,2 method after second time at menu, with again ++ and if (again>0) //syntax, not helping as well.
I've squeezed what I've learned before but no luck, can't find similar problem.
Any help would be appreciated, thank you.
Problem Solve by running cin.ignore() only when first time access
void passengerRecord()
{
int again = 0;
char option;
do
{
//menu syntax
//.
//.
if (again == 0) // only run when it's first time access during this call
cin.ignore();
while (option != '1' && option != '2' && option != '3' && option != '0')
{
//error input correction
}
//proceed to sub-menu
again++; // increment or again = 1; to indicate the menu had been accessed during this call
} while (option != '0');
}
Hmm, the only certainty is: if you use cin prior to calling get(), you may need to flush the buffer and clear the flags (example below):
#include<iostream>
#include <vector>
using namespace std;
void passengerRecord(){
char option;
//Uncomment the below if cin was use prior to this function and not safely emptied.
//cin.ignore(INT_MAX, '\n');//Ignore with delimiter newline
//cin.clear();//Clear flags in cin
do
{
//system("CLS");//Commented to display data;
cout << "Please tell me what you want to do." << endl;
cout << "1. Add Passenger Record" << endl;
cout << "2. Edit Passenger Record" << endl;
cout << "3. Delete Passenger Record" << endl;
cout << "0. Back to System Module Menu" << endl;
cout << "Your choice: ";
cin.get(option);
cin.ignore(INT_MAX, '\n');//Ignore with delimiter newline
cin.clear();//Clear flags in cin
while (option != '1' && option != '2' && option != '3' && option != '0')
{
system("CLS");
cout << "Error Input! Please try again." << endl;
cout << "Please tell me what you want to do." << endl;
cout << "1. Add Passenger Record" << endl;
cout << "2. Edit Passenger Record" << endl;
cout << "3. Delete Passenger Record" << endl;
cout << "0. Back to System Module Menu" << endl;
cout << "Your choice: ";
cin.get(option);
cin.ignore(INT_MAX, '\n');//Ignore with delimiter newline
cin.clear();//Clear flags in cin
}
switch (option)
{
case '1':
cout << "passengerAddsa();" << endl;
break;
case '2':
cout << "passengerEditsa();" << endl;
break;
case '3':
cout << "passengerDeletesa();" << endl;
break;
case '0':
cout << "Redirecting back to module menu...";
cin.ignore(INT_MAX, '\n');//Ignore with delimiter newline
cin.clear();//Clear flags in cin
break;
default:
cout << "Exception error occurred!";
}
} while (option != '0');
}
int main() {
passengerRecord();
return 0;
}
So I have a Menu that I used to run my text based game. The problem is that I can't seem to exit my game.Every time I run it, I can do option 1 and go to my game, and options 2 and 3 work just fine. But For option 4, I am unable to exit my game. All it does is print out what I ask it to print out, before giving the menu options again (as if it was just looping).
I have googled a lot, and tried to figure out why but I am not sure.
If someone can advise me what to do or tell me where my mistake is, it would be greatly appreciated. Please let me know if you want to see more code. All I have displayed here is the Menu Function.
void menu() {
char choice = -1;
while(choice != '1')
{
cout << "\n* * * * *" << endl;
cout << " The Dark Maze\n";
cout << "\n* * * * *" << endl;
cout << "\n=====================";
cout << "\n Main Menu |";
cout << "\n=====================";
cout << "\n 1 - Start Game |";
cout << "\n 2 - Instructions |";
cout << "\n 3 - Storyline |";
cout << "\n 4 - Exit |";
cout << "\n=====================";
cout << "\n";
cout << "\n Enter choice: ";
cout << "\n";
cin >> choice;
switch (choice)
{
case '1':
cout << "\n" << endl;
cout << "\n But we can't start the game just yet..." << endl;
break; //heads to game
case '2':
Instructions();
break;
case '3':
Storyline();
break;
case '4':
cout << "\n Well, if you really don't want to play... you don't have to." << endl;
break; //just say exit?? break isnt making it stop
default:
cout << "Invalid Character entered\n";
cout << "\n";
cout << "Press Space to continue\n";
}// end of switches
cin.get();
} // end of while
}// end of menu
You shouldn't be using while loop for this. Try do-while loop for this kind of menus like this:
do
{
// your menu here...
cin >> choice;
switch ( choice )
{
case ...
...
}
// cin.get();
// ^^^^^^^^^^ You don't need this...
} while ( choice != '4' );
Some points to help you:
Use an enum to define your menu choices. (OR an enum class).
You can simply write a printMenu() function to print the menu in the main loop. Another function to process the choice.
For example:
void startGame()
{
char choice = INVALID_OPTION; // INVALID_OPTION => default invalid value
do
{
printMenu();
cin >> choice;
processChoice( choice );
} while ( choice != EXIT ); // EXIT => #define or an enum
}
You can use exit() to terminate your program with a given return value:
case '4':
std::cout << "blahblahblah";
std::exit(0);
break; // No longer necessary
It's prerequisite and prototype is
#include <cstdlib>
namespace std{
void exit(int status);
}
just use return instead break blow case '4' . not perfect but can work.
For some reason, it goes into the cin statement the first time but then skips it every other time in this code. After running it a few times, I realized it goes into the default case for some reason without even asking for the user input. Why?
Here's the code. It's a menu with a huge switch statement. The functions inside the switch statements aren't relevant here since it's just the overall loop.
int main()
{
Document* myDocs = new Document[10];
int docCount = 0;
bool menu = true;
int userInput = 0;
while ( menu == true )
{
//int userInput = 0;
userInput = 0;
cout << "----------------MENU----------------" << endl << endl;
cout << " --------(1) LOAD DOCUMENT (1)--------- " << endl << endl;
cout << "--------(2) OUTPUT DOCUMENT (2)--------" << endl << endl;
cout << " --------(3) ANALYZE DOCUMENT (3)-------- " << endl << endl;
cout << " ------(4) COMPARE TWO DOCUMENTS (4)------ " << endl << endl;
cout << " ----------(5) ENCRYPT (5)---------- " << endl << endl;
cout << "-----------(6) DECRYPT (6)----------" << endl << endl;
cout << "-------------(7) EXIT (7)--------------" << endl << endl;
cin >> userInput;
string docName;
string outputLoc;
switch (userInput)
{
case 1:
// Function
break;
case 2:
// Function
break;
case 3-8:
// Function
break;
default:
break;
}
Basically, I first enter the first userinput. Let's say I enter 1. Then it goes into case 1. But then after it gets out of case 1, it goes into an infinite loop that keeps displaying the menu. Shouldn't it stop at the cin statement? That's what I dont understand.
EDIT::
Case 1 is the primary one i'm worried about since I'm trying them 1 by and 1 and case 1 doesn't work.
This is the full code for case 1:
case 1: // Load Document
{
string inputLoc;
cout << "Please input the document name:" << endl;
cin >> docName;
myDocs[docCount].setName(docName);
myDocs[docCount].id = docCount;
cout << "Input Location: " << endl;
cin >> inputLoc;
myDocs[docCount].loadDocument(inputLoc);
docCount++;
break;
}
I'm starting to speculate there is something wrong with my loadDocument function.
Here is the code for that:
void Document::loadDocument(string name)
{
ifstream myFile(name);
int numOflines = 0;
string theLine;
char words;
while (myFile.get(words))
{
switch (words)
{
case '.':
numOflines++;
break;
case '?':
numOflines++;
break;
case '!':
numOflines++;
break;
}
}
lineCount = numOflines;
setLineCt(numOflines);
arr = new Line[lineCount];
myFile.close();
char theChar;
ifstream myFile2(name);
int key = 0;
if (myFile2.is_open())
{
for ( id = 0; id < lineCount; id++ )
{
while (myFile2>> noskipws>>theChar && theChar != '.' && theChar != '!' && theChar != '?') // Changed from || to &&
{
//myFile2>> noskipws >> theChar;
theLine[key] = theChar;
key++;
}
myFile2>>theChar;
arr[id].setStr(theLine);
}
}
}
Basically I'm trying to load the document and store the word count and line count from it. Is there something wrong in it?