C++ how to allow user to choose choice - c++

Hi i dont know how to allow the user to choose one of the choices i provided in my code and if they picked a choice that was not given then i want the program to return to the last point.
This is my code
#include <iostream>
#include <string>
using namespace std;
int main()
{
//Welcoming message with date//
cout << "Welcome to FILM Screen Cinema" << endl;
cout << endl;
cout << "ENTER STAFF/OPERATOR'S NAME: ";
string name;
cin >> name;
cout << endl;
cout << "ENTER DATE:";
string date;
cin >> date;
cout << endl;
cout << "CHOOSE A MOVIE THAT IS SCREENING TODAY:" << endl;
cout << "[1] Deadpool" << endl << "[2] Goosebumps" <<endl;
string input;
cin >> input;
}
Where it says choose a movie, i want the user to type either 1 or 2 for the choices but if they type any other number then it should say invalid and allow them to type 1 or 2 again. Thank you in advance.

I suspect you want each of the std::cin >> XXX calls to actually query the user for input. That is currently not the case, for example when the user types "John Smith" as the name of the operator, name will be set to "John", and the following std::cin >> date reuses the remaining part "Smith" instead of asking for input again.
To fix this, you can use std::getline.
The first part of your code should thus be replaced by
std::cout << '\n';
std::cout << "ENTER STAFF/OPERATOR'S NAME: ";
std::string name;
std::getline(std::cin, name);
std::cout << '\n';
std::cout << "ENTER DATE:";
std::string date;
std::getline(std::cin, date);
std::cout << '\n';
The same is true for the part where you validate the input. Now you only need to add a while-loop to keep asking the user for new input if the previous one was invalid.
std::cout << "CHOOSE A MOVIE THAT IS SCREENING TODAY:\n";
std::cout << "[1] Deadpool\n"
<< "[2] Goosebumps\n";
std::string input;
std::getline(std::cin, input);
while(input != "1" && input != "2") {
std::cout << "Invalid!\n\n";
std::cout << "CHOOSE A MOVIE THAT IS SCREENING TODAY:\n";
std::cout << "[1] Deadpool\n"
<< "[2] Goosebumps\n";
std::getline(std::cin, input);
}
if (input == "1") {
// do something
} else if (input == "2") {
// do something else
}
Btw, please consider reading “\n” or '\n' or std::endl to std::cout? and Why is “using namespace std” considered bad practice?

Related

How can I repeat all of this code under one circumstance and only some of it under another?

Sorry for the vague title - wasn't sure how to phrase it without just showing what I'm trying to do.
If the user enters '2' (No), I'd like all of the code you see here to repeat so that the user can re-enter their name. In the current version of my code, that works fine. The problem occurs when the user enters any number other than '1' or '2'. If they enter 3 or anything else, I'd like the terminal to print "Invalid entry" and then repeat all of the code from line 11 downwards. My problem is that I can't figure out how to get these two behaviors to be capable of working at the same time.
std::string assign_name()
{
std::string name;
int confirm_name = 0;
do {
std::cout << "\nWhat is your name?\n\n";
std::cin >> name;
std::cout << "\n\nYour name is " << name << "?\n";
std::cout << "1. Yes\n";
std::cout << "2. No\n\n";
std::cin >> confirm_name;
} while (confirm_name != 1);
return name;
}
I've tried organizing the code in a bunch of different ways, but the solution just isn't coming to me. Any help's appreciated - thanks.
Edit: Wrapping the last part of the function in its own separate do statement worked perfectly.
I suggest you use an if else statement so that it can continue if condition is not met. In your code u did not specify what should happen when the answer is not 1 or 2
As noted in the comments, you can use if / then / else. There are a lot of different ways you can use control statement (if / then, do / while, etc..) to achieve the desired behavior...
std:string name, confirm_name;
bool done;
std::cout << "\nWhat is your name?\n\n";
do
{
std::cin >> name;
std::cout << "\n\nYour name is " << name << "?\n";
std::cout << "1. Yes\n";
std::cout << "2. No\n\n";
std::cin >> confirm_name;
if (confirm_name == "1")
{
done = true;
}
else if (confirm_name != "2")
{
std::cout << "invalid value";
}
}
while (!done);
1 - After the user confirms their name, add an if statement to check whether their input matches 1 or 2, if not, then send invalid entry message
2 - Set the while loop to iterate again if the user response did not match 1 or 2.
#include <iostream>
#include <string>
std::string assign_name()
{
std::string name;
int confirm_name = 0;
do {
std::cout << "\nWhat is your name?\n\n";
std::cin >> name;
std::cout << "\n\nYour name is " << name << "?\n";
std::cout << "1. Yes\n";
std::cout << "2. No\n\n";
std::cin >> confirm_name;
if (confirm_name != 1 && confirm_name != 2)
{
std::cout << "Invalid entry\n";
}
} while (confirm_name != 1 || confirm_name !=2);
return name;
}
int main()
{
assign_name();
}

The while loop keeps executing no matter whatever the second user input is within the second case of the switch

The code has been updated in order to solve a different section of the whole picture within the coding process. Now I need help within the second case of the switch. The problem now is that the while loop always executes within the second function of the switch. I don't no if the array is verifying the number or the user input.. I could use while (string::npos != studID2[i].find_first_of(studID2[a])) I need some help here it is getting very complex and I am hitting a brick wall.
1)I need to verify each user input using a for loop and two arrays. I tried to increment the of the arrays in order to execute the while statement.
2) If the condition is true the while loop will execute telling the user that he must enter 3 different digits, the reason why I am using an array and a for loop is because the user gets to choose how many names and IDs he would like to input into the archive.
3) The for loop increments a++ in order to check to see if the last input is the same as the newest user input.
It is getting too complex here any help would be appreciated.
Number 4 is the expected error...
4) The second user input will always make the while loop run regardless of what digits you use.
5)The reason for so much code is because I am not completely sure where the problem begins and the problem ends...
6)I am using two arrays here in this problem.
7)There is another error if you change the a from 0 to 1 it will automatically close the program. The reason you would change the a to a 1 is so that a will increment by 1.
//I am trying to verify multiple inputs with a array and a for loop..
// The expected output is that the second ID you input in the second option of the switch case is going to execute the while loop.
//I am trying to execute the while loop properly within the second function of the switch case.
//I need help any form of help can be appreciated.
#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
#include <cstddef>
#include <limits>
#include <cstdlib>
int name2 = 0;
int studentID = 0;
int email2 = 0;
int studentID2[100];
std::string let("abcdefghijklmnopqrstuvwxyz");
int numbers = (1, 3, 0);
std::string str;
std::string name;
std::string studID;
std::string studID2;
std::string email;
std::string emailbackup;
std::string studFinal;
std::stringstream concatenate;
std::stringstream concatenatetwo;
int x;
std::string fileName = "StudentArchive.txt";
void emailEntry();
void readDocument();
int readNumber();
void deleteInformation();
void getStudentinformation();
using std::cout;
using std::cin;
int main()
{
do {
std::cout << "What would you like to do?" << std::endl;
std::cout << "1)Would you like to see the archive?" << std::endl;
std::cout << "2)Would you like to register student information?" << std::endl;
std::cout << "3)Would you like to find a student within the registry?" << std::endl;
std::cout << "4)Delete all student information?" << std::endl;
std::cout << "5)Exit Program?" << std::endl;
std::cin >> x;
switch (x)
{
case 1:
readDocument();
break;
case 2:
emailEntry();
break;
case 3:
deleteInformation();
break;
case 4:
getStudentinformation();
break;
case 5:
cout << "Exiting Program." << std::endl;
system("PAUSE");
break;
}
} while (x != 5);
}
void emailEntry()
{
std::ofstream outfile;
outfile.open(fileName, std::ios_base::app);
int amountofStudent;
std::cout << "How many student Identities would you like to enter?" << std::endl;
std::cin >> amountofStudent;
cin.ignore();
Here is where the user chooses how many students he would like to enter into the registry. I am having difficulty verifying the user input regarding the studentIDs.
if (outfile.is_open()) {
for (int i = 0; i < amountofStudent; i++)
{
std::string studID2[100];
std::stringstream(name) >> name2;
cout << "Please enter your name.." << std::endl;
getline(cin, name);
outfile << name;
std::stringstream(name2) >> name;
while (std::string::npos != name.find_first_of("0123456789"))
{
cout << "You must have letter within user input." << std::endl;
cout << "Please enter your name." << std::endl;
getline(cin, name);
outfile << name;
}
//I need to check to see if the first 3 numbers are correct?
//The student ID must be at least 6 digits, and the first 3 numbers must be 130.
cout << "Please enter Your student I.D." << std::endl;
getline(cin, studID);
outfile << studID;
std::stringstream(studID) >> studentID;
while (/*std::string::npos != studID.find_first_of("130") */ studentID != 130 /*&& studID.length() <= 6*/)
{
std::stringstream(studentID) >> studID;
cout << "You must enter 130 as the first 3 digits" << std::endl;
getline(cin, studID);
std::stringstream(studID) >> studentID;
}
//==============
//std::stringstream(studentID2) >> studID2[i];
cout << "Please enter the second part of the student I.D. " << studentID << "-" << std::endl;
getline(cin, studID2[i]);
outfile << studID;
//outfile << studID2[i];
std::stringstream(studID2[i]) >> studentID2[i];
//cout << i;
This is the for loop, and array I need help with. Below this text is where I am having problems. I don't understand why the while loop won't execute I am trying to verify the first user input with the next user input. For example if the user enters 888 on the first input then tries to enter 888 on the second input they need to re-enter different digits or the input will go on forever. The main struggle is if the user chooses to enter multiple student accounts within this minor registry.
for (int a = 0; a < i; i++)
{
while (studID2[i] == studID2[a])
{
cout << "The numbers cannot be repeated you must re-enter the student ID." << std::endl;
std::stringstream(studentID) >> studID;
cout << "You must enter 130 as the first 3 digits" << std::endl;
getline(cin, studID);
std::stringstream(studID[i]) >> studentID;
//std::stringstream(studID2[i]) >> studentID2;
cout << "Please enter the second part of the student I.D. " << studentID << "-" << std::endl;
getline(cin, studID2[i]);
outfile << studID;
outfile << studID2[i];
//std::stringstream(studID2[i]) >> studentID2;
}
}
This is where the verification of the studentIDs end...
while (/*std::string::npos != studID.find_first_of("130") */ studID2[i].length() < 3 || studID2[i].length() > 3)
{
//stringstream(studentID) >> studID;
cout << "Add 3 more digits." << std::endl;
getline(cin, studID2[i]);
outfile << studID2[i];
}
concatenate << studentID << "-" << studID2 << std::endl;
studFinal = concatenate.str();
/*while (studID.length() != 6)
{
cout << "You must enter 130 as the first 3 digits and you must have 6 digits." << std::endl;
std::cin >> studID;
}*/
cout << "Please enter your email.." << std::endl;
std::stringstream(email) >> email2;
getline(cin, email);
outfile << email;
std::stringstream(email2) >> email;
while (email == emailbackup || email.empty())
{
cout << "Please enter your email..." << std::endl;
std::stringstream(email) >> email2;
getline(cin, email);
outfile << email;
std::stringstream(email2) >> email;
}
concatenatetwo << email << "#atlanticu.edu" << std::endl;
email = concatenatetwo.str();
emailbackup = email;
cout << "Your email is" << email << std::endl;
std::system("pause");
}
}
outfile.close();
}
Here is where the user deletes info..
void deleteInformation()
{
std::ofstream infile(fileName, std::ios::trunc);
if (infile.is_open()) {
cout << "You have now have no books." << std::endl;
system("PAUSE");
system("cls");
infile.close();
}
}
void getStudentinformation()
{
std::ifstream outfile;
outfile.open(fileName);
if(outfile.is_open())
{
int x;
cout << "1)Name" << std::endl;
cout << "2)studentNumber" << std::endl;
cout << "3)Exit" << std::endl;
cin >> x;
switch (x)
{
case 1:
cout << "Please enter the student's name.." << std::endl;
getline(cin, name);
cout << name << std::endl;
outfile >> name;
break;
case 2:
cout << "Please enter the first 3 digits of the student's ID number.. " << std::endl;
getline(cin, studID);
cout << "Please enter the last 3 digits of the student's ID number.. " << std::endl;
getline(cin, studID2);
outfile >> studID;
outfile >> studID2;
break;
case 3:
std::string choice;
cout << "Would you like to return to the main menus?" << std::endl;
cin >> choice;
break;
}
}
}
int readNumber()
{
int number;
cin >> number;
std::string tmp;
while (cin.fail())
{
cin.clear();
std::getline(cin, tmp);
cout << "Only numbers please: ";
cin >> number;
}
getline(cin, tmp);
return number;
}
Here is where the user reads the txt doc.
void readDocument()
{
std::ifstream infile;
infile.open(fileName);
if (infile.is_open()) {
std::string info;
while (getline(infile, info))
{
cout << info << std::endl;
}
infile.close();
}
else {
cout << fileName << " doesn't exists !" << std::endl;
}
std::system("PAUSE");
std::system("cls");
}
//std::ofstream outfile;
//outfile.open(fileName, ios_base::app);
//if(outfile.is_open()) {
// cout << "How many books do you want to add: ";
// int n = readNumber();
// while (n <= 0)
// {
// cout << "Only positive numbers, please: ";
// n = readNumber();
// }
// for (int i = 0; i < n; i++) {
// string title = "Book's Title: ";
// cout << title;
// title += readText();
// string author = "Author: ";
// cout << author;
// author += readText();
// string genre = "Book's Genre: ";
// cout << genre;
// genre += readText();
// cout << endl;
// outfile << title << endl;
// outfile << author << endl;
// outfile << genre << endl << endl;
// }
//}
// outfile.close();
// cout << "Books have been added to the library !" << endl;
// system("PAUSE");
// system("cls");
Think about your function signature.
void email(string emailbackup);
Do you actually want the caller to pass a string to the function email()?
Because you then define emailbackup inside the function again.
You want something like this probably...
...
case 2:
const string backup = "backup#email";
email(backup);
break;
...
void email(string emailbackup)
{
// string emailbackup; // delete this line
...
}
Also, remove using namespace std; and be consistent with your namespace usage. Why add using namespace cout, cin etc if you are calling them with the namespace explicitly i.e. std::cin, std::cout.
Either add using namespace std::cout and use cout rather than std::cout or vice versa. Don't mix it up. Same with std::string and string. Makes it look like you defined your own string...
Just one last thing, for the sake of readability I would suggest breaking this email function into smaller functions. For instance:
void email(string emailbackup)
{
...
int studentID = getStudentID();
string studentEmail = getStudentEmail();
...
}
int getStudentID()
{
int studentID;
cout << "Please enter Your student I.D." << std::endl;
std::cin >> studID;
stringstream(studID) >> studentID;
while (/*std::string::npos != studID.find_first_of("130") */ studentID != 130 /*&& studID.length() <= 6*/)
{
stringstream(studentID) >> studID;
cout << "You must enter 130 as the first 3 digits" << std::endl;
std::cin >> studID;
stringstream(studID) >> studentID;
}
return studentID;
}

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/)

Why does usernametwo always get skipped?

I am trying to learn C++, anyway I am on if statements.
I coded a program that ask a two user their full name and ages (fictional users), it ask user1 its name and age and user2 the same, but somehow asking the user2's name gets skipped and end up asking the user2's age
why ?
here is my code :
#include <iostream>
#include <string>
using namespace std;
int main()
{
string usernameone;
string usernametwo;
int age1;
int age2;
//ask the users their name and age
cout << "Hi may I know your full name ? : ";
getline ( cin, usernameone, '\n');
cout << "\nHello " << usernameone << " May I know now whats your age ? : ";
cin >> age1;
cout << "Ok thanks for the information, now may I talk to the other user ? thanks.\n\n";
cout << "Hello may I know your full name ? : ";
getline ( cin, usernametwo, '\n');
cout << "\nHello " << usernametwo << " May I know now whats your age ? : ";
cin >> age1;
if(age1 < age2)
{
cout << "looks like " << usernameone << " is older than " << usernametwo;
}
else
{
cout << "ok " << usernametwo << " is older than " << usernameone;
}
if(age2 && age1 >= 100)
{
cout << "your both lying your age can't be 100 and above";
}
cin.ignore();
cin.get();
return 0;
}
cin >> age1;
cout << "Ok thanks for the information, now may
I talk to the other user ? thanks.\n\n";
cout << "Hello may I know your full name ? : ";
leaves '\n' in input stream and you are reading it in the next read
getline ( cin, usernametwo, '\n');
You can ignore this character with:
cin >> age1;
cout << "Ok thanks for the information, now may
I talk to the other user ? thanks.\n\n";
cout << "Hello may I know your full name ? : ";
cin.ignore();
getline ( cin, usernametwo, '\n');

reading and printing inputs and C-string in C++

I have a simple program to read and echoed the user's input and calculate the total amount. I'm having trouble with arrays. I want to know how to use an array to read and print each product name and the cost and the find grand total upon checkout. Should I also use functions?
#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;
const int MAX_CHAR = 100;
void pause();
int main()
{
char productName[MAX_CHAR];
double price;
char reply;
double total = 0;
cout << fixed << showpoint << setprecision(2);
cout << "Welcome to your shopping calculator!" << endl;
do {
cout << "Enter the product name: ";
cin.get(productName, MAX_CHAR, '\n');
cin.ignore(100, '\n');
cout << "Enter the amount: $";
cin >> price;
while (!cin) {
cin.clear();
cin.ignore(100, '\n');
cout << "Invalid amount. Please enter the amount: $";
cin >> price;
}
cin.ignore(100, '\n');
cout << "The product name is" << " " << productName << " "
<< " and it costs" << " " << "$" << price << endl;
total += price;
cout << "The total amount is " << " " << total << endl; //program needs to keep a running total
cout << "Would you like to continue shopping? (y/n): ";
cin >> reply;
cin.ignore(100, '\n');
} while ( reply == 'Y' || reply == 'y'); //the program will continue until the user wants to checkout
pause();
return 0;
}
void pause()
{
char ch;
cout << "Press q followed by Enter key to continue....." << endl;
cin >> ch;
}
Thanks for the help!
You need to map the product name to the cost using std::map so that you can print the respective pairs afterwards. As for the grand total, that's stored in the variable total so printing it is trivial.
To do this, you will need to include the <map> header, as the Standard Library class std::map is defined there. Moreover, I've also included some changes to your code that should be considered. In particular, using std::string and using std::numeric_limits<...>::max() to return the constant.
#include <iostream>
#include <string>
#include <map>
int main()
{
std::string productName;
double price;
char reply;
double total = 0;
std::map<std::string, double> productToPrice;
std::cout << std::fixed << std::showpoint << std::setprecision(2);
std::cout << "Welcome to your shopping calculator!" << std::endl;
while ((std::cin >> reply) && (reply == 'y' || reply == 'Y'))
{
cout << "Enter the product name: ";
std::cin >> productName;
cout << "Enter the amount: $";
while (!(cin >> price))
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cout << "Invalid amount. Please enter the amount: $";
}
total += price;
productToPrice.insert(std::make_pair(productName, price));
cout << "Would you like to continue shopping? (y/n): ";
}
...
}
Note the changes I made. Please use them.
To print you simply do:
typedef std::map<std::string, double>::const_iterator iter_type;
for (iter_type beg(productToPrice.begin()),
end(productToPrice.end()); beg != end; ++beg)
{
std::cout << beg.first << " -- " << beg.second << std::endl;
}
std::cout << "\nThe total price is: " << total;
You are definitely on the right track. I think you are mixing I/O conventions in C and C++ which is causing a lot of your issues. It would be very helpful if you could elaborate on what exactly your issues are.
Carpetfizz is correct in that since you don't know the number of items at compile time, you will need to use a dynamic array with std::vector. You can learn about vectors here.
In addition, C++ has a very useful string data type that you can include with #include <string>. Using this, as well as a junk string such as string junk;, you can avoid using cin.ignore(...) and get cleaner I/O by using getline(cin, junk).
I strongly recommend doing this because creating a vector of C-strings or C-style strings is a pain, because C-style strings are actually arrays of characters, so you'd have to use std::vector<std::vector<char> > products.