I recently started working on a project. The task is the following:
Write a program to keep a list of available items in a sports goods store. For each item, the following information must be stored: Name, Manufacturer, Price, Available items. The program should support the following features, as a text menu from which the user can choose:
• Enter a new item in the list
• Search by Manufacturer of an item
• Sort items in the list by Name
• Display the current content of the list
I was advised this on another topic:
1) For the menu, you would make a function that displays the information and returns the input after verifying that it's a valid input. You can use pass by reference. Don't bother about functions if you haven't learn it yet. Then just use switch case like you said.
2) For adding an item, (again make a function if you have learnt about it) make a temporary ITEMS object and ask the user for the various required inputs like price and then directly read the inputs into the object (eg. cin >> object.price). After getting all information, simply push the object into the vector we had.
3) For searching by Manufacturer's name you simple need to compare the given name with the manufacturer's name from each element of the vector.
4) Sort the elements of the vector based on their name parameter.
5) Simply print out all parameters of each element in the vector.
I will create a vector after learning more about them, and I will enter below the code which I have written so far. My questions here is should i follow the five tips on top or not. If you think I should not, please share your insights with different suggestions. I know this topic will probably be closed because I did read all the rules but still some information could be crucial. Thanks in advance and I'm sorry if this essay of mine has been time-consuming.
#include <iostream>
#include <conio.h>
#include <string.h>
#include <dos.h>
#include <vector>
using namespace std;
struct articles
{
char name[20];
char manufacturer[15];
double price;
char available;
};
int main()
{
int choice;
do
{
cout << ("\n ##################################################");
cout << ("\n # Menu #");
cout << ("\n # 1.Enter new article #");
cout << ("\n # 2.List of manufacturers of articles #");
cout << ("\n # 3.Sort articles by name #");
cout << ("\n # 4.Display the current content of the list #");
cout << ("\n # 5. End of program #");
cout <
< ("\n ##################################################") << endl;
cin >> choice;
switch (choice)
{
case 1:
articles newart;
cout << ("Enter a name: ");
cin >> (newart.name);
cout << ("Enter a manufacturer: ");
cin >> (newart.manufacturer);
cout << ("Enter a price: ");
cin >> (newart.price);
cout << ("Enter if its available (y/n): ");
cin >> (newart.available);
cout << ("The new article you've created is the following: \n");
cout << newart.name << endl;
cout << newart.manufacturer << endl;
cout << newart.price << endl;
cout << newart.available << endl;
break;
/* case 2:
//code
break;
case 3:
//code
break;
case 4:
//code
//extra information about the mode and the controller
break;
case 5:
cout << "End of Program.\n";
break;
*/
default:
cout << "Not a Valid Choice. \n"
<< "Choose again.\n";
break;
}
}while (choice != 5);
return 0;
}
Related
I'm quite new to C++ and my assignment is pretty tough. I must create a menu (in which I'm struggling quite badly), not only that but I should also read and display a textfile. So far, the only method I used only displays the first lines of the text file. Can you help me out? Thanks in advance.
The break function when added to the first case also makes the loop an infinite wall of texts! I dont know what to do..
// Assignment 1.cpp : Tally Ho Generator
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int runMenu;
int main()
{
int menuInput;
bool menu = true;
ifstream inFile;
string ABOUT;
// Menu Interface
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
cout << " The Tally Ho Probability Generator (MCD4720_Assignment 1)\n";
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
cout << " [1] End Testing the Program\n";
cout << " [2] Display About Information\n";
cout << " [3] Read and store data from files\n";
cout << " [4] Generate a Dice Tally Table\n";
cout << " [5] Save Tally Statistics to a file\n";
cout << " [6] Load Tally Statistics from a file\n";
cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
cout << "Which Option would you like (1-6)\n";
cin >> runMenu;
// Menu Input Function
while (menu != false) {
switch (runMenu)
{
case 1:
{
inFile.open("C:\\Users\\William\\Documents\\MCD Assignment 4720 1\\TallyAbout.txt");
while (getline(inFile, ABOUT)) {
cout << ABOUT << endl;
inFile.close();
}
break;
}
case 2:
{}
case 3:
{}
case 4:
{}
case 5:
{}
case 6:
{}
default: {
cout << " Input unrecognized, please choose again \n";
cin >> runMenu;
break;
}
}
}
cin.ignore();
cin.get();
return 1;
}
So far, the only method I used only displays the first lines of the text file
That is because you close the file after reading the first line:
while (getline(inFile, ABOUT)) {
cout << ABOUT << endl;
inFile.close(); // <------ here !!
}
You do not need to close the file explicitly. The file is closed in the destructor of inFile.
The break function when added to the first case also makes the loop an infinite wall of texts! I dont know what to do..
That is because break breaks out of the switch. No other case will be handled. In particular, your default case where you ask for user input will not be executed. Actually you never modify the value of menu and while(menu != false) is an infinite loop. Move the part that has to be done for any case out of the switch:
while (menu != false) {
switch (runMenu)
{
case 1:
{
inFile.open("C:\\Users\\William\\Documents\\MCD Assignment 4720 1\\TallyAbout.txt");
while (getline(inFile, ABOUT)) {
cout << ABOUT << endl;
inFile.close();
}
break;
}
//...
default: {
cout << " Input unrecognized, please choose again \n";
break;
}
}
cin >> runMenu;
// put logic here, for example:
menu = (runMenu == 1);
}
You should modify the output accordingly. Currently it says " Input unrecognized, please choose again ", but if I understand correctly, the user has to choose to continue or not on every iteration. Also using one and not two variables for menu and runMenu would be less error-prone.
Try this:
case 1:
{
inFile.open("C:\\Users\\William\\Documents\\MCD Assignment 4720 1\\TallyAbout.txt");
while (getline(inFile, ABOUT)) {
cout << ABOUT << endl;
}
inFile.close();
break;
}
You are closing the file after you read the first line
The difference now is that you close the file after you read all lines
I've been programming for a while (in Prolog, Scheme, and a little bit in C), but I recently decided to brush up on my C++ knowledge. I solved a problem that was meant to illustrate vectors. It was essentially a project to create a database that creates a vector to temporarily store the various games that the user inputs into it, and removes the ones they don't want. The code itself is running fine, not as pretty as scheme or Prolog could do it, but it works.
However, I accidentally typed "Control P" into the first prompt of the program and I got the strangest result: it started an infinite loop. I tried it again with "Control Z" and I got the same result. I haven't tried any other key combos, but I imagine that some others could be found. It's not a super worrying problem, but I am curious to know why it's doing this. Is it something about C++, or is it just Visual Studio? Anyway, here's the source:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
cout << "Welcome to the Cpp Games Database!";
int x = 0;
string game = "";
vector <string> games;
vector <string>::const_iterator iter;
while (x != 4){
cout<< "\n\nPlease choose from the list bellow to decide what you want to do:\n";
cout<< "1. Add Games to the Database.\n"
<< "2. Remove Games from the Database.\n"
<< "3. List all the Games.\n"
<< "4. Exit.\n"
<< "\n(Type the number of your choice and hit return)\n";
cin >> x;
switch (x){
case 1:
game = "";
do{
cout << "\nPlease Input a Game (type esc to exit): ";
cin >> game;
games.push_back(game);
} while (game != "esc");
games.pop_back();
break;
case 2:
game = "";
do{
cout << "\nPlease input the game you would like to remove(or type esc to exit): ";
cin >> game;
iter = find(games.begin(), games.end(), game);
if(iter != games.end())
games.erase(iter);
else cout << "\nGame not found, try again please.\n";
} while (game != "esc");
break;
case 3:
cout << "\nYour Games are:\n";
for (iter = games.begin(); iter != games.end(); iter++)
{
cout << endl << *iter << endl;
}
break;
default: break;
}
}
return 0;
}
Since you are not inputting valid data for cin it is stuck there waiting for the data to be reprocessed or discarded for new input. You need to check your input and only accept valid data. Essentially cin is keeping the original data it's given and continuously trying to process it.
Always verify your input and discard it if it's invalid.
Here is another answer on the same problem for some more insight (with source).
https://stackoverflow.com/a/17430697/1858323
I have a C++ project to do for my class and it's quite intricate, to me at least. I've got the general idea and concept down, but i'm running into some other problems when it comes to the arrays and file stuff. Below is what the project consists of
You will be building and modifying a class roster system for a Teacher to manage his class roster and their final grades. This program
will use functions for the various menu options, and you will work with
the data in arrays or vectors. The program will provide a menu system that allows for the teacher to perform tasks until he chooses to close the program. The program will read and write to a file called
classroster.txt. Any and all additions, deletions, or changes to the roster will be saved in classroster.txt file.
This file will contain the names of each of the students in the class with their grade. See the following for an example listed below of how the data would be stored in the classroster.txt file. You should work with the data using arrays or vectors.
Jim Jones C
Kevin James B
Marc Cohen A+
When the program starts it should read the data from the classroster.txt into arrays or vectors. While the program is running it should use the arrays or vectors for the functions while using the program. When the program ends it should overwrite the classroster.txt file if something has been changed. The
programs menu will offer the following options and will allow the user to keep performing functions until they choose to exit the program ( hint !!!!! you will need to use a loop for the menu system)
Add A New Student-
This will allow the user to add a new student to the system. The system should prompt for the new students full name and then grade.
It should validate that the grade is in the following values
(A+, A, A-, B+, B, B-,C+,C, C-, D+, D, D-, F) and if not
in the approved list it should prompt the user for a valid grade.
Change a Students Grade-
This will find the student in question and change the grade. If the specified student doesn’t exist the program should print an error message telling the user that you couldn’t find the specified student to
change their grade.
Remove a Student-
Will remove a student and their grade from the roster. If the specified student doesn’t exist the program should print an error message telling the user that you couldn’t find the specified student to remove.
Display Class Roster–
(Bonus Points if you can display the names is alphabetical order) This
function will display the list of all the students and their grades on
the screen that looks like this:
Student Name Grade
Jim Jones C
Kevin James B-
Marc Cohen A+
This is what i have so far, it's obviously not done yet
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
const int num_of_students;
const int new_student = 1, change_grade = 2, remove_student = 3, display_roster = 4, quit = 5;
int classroster[num_of_students];
int student_grade[num_of_students];
string possible_grades[13] = {"A+", "A", "A-", "B+", "B", "B-", "C+", "C", "C-", "D+", "D", "D-", "F"};
int choice;
ofstream class_file;
cout << "How many students do you have in your class?" << endl;
cin >> num_of_students;
cout << "---MENU---" << endl;
cout << "1. Add A New Student" << endl;
cout << "2. Change A Students Grade" << endl;
cout << "3. Remove A Student" << endl;
cout << "4. Display Class Roster" << endl;
cout << "5. Quit" << endl;
cout << "Enter your choice: ";
cin >> choice;
if (choice == new_student) {
for (int index = 0; index < num_of_students; index++) {
class_file.open("classroster.txt");
cout << "What is the name of the student you want to add? ";
getline(cin, classroster);
if (student_grade == possible_grades) {
cout << "What is the final grade of this student? ";
getline(cin, student_grade);
}
else {
"Please enter a valid grade!"
}
cout << "Student added!";
}
}
else if (choice == change_grade) {
class_file.open("classroster.txt");
cout << "What is the name of the student whose grade you want to change? ";
getline(cin, )
}
else if (choice == remove_student) {
}
else if (choice == display_roster) {
}
else if (choice == quit) {
}
else {
cout << "Please enter a valid choice!"
}
system("PAUSE");
return 0;
}
First, to answer your question, here's one way to search an array of student names:
int index = -1;
for(int k=0; k<num_of_students; ++k)
{
if(names[k] == name)
index = k;
}
And here's a way to change the array of grades:
student_grade[index] = 3;
More generally, you taking the wrong approach. Your code does not compile, so it looks as if you're writing it all out before testing any of it. As they never seem to teach in school, you should start with something small and simple, add complexity a little at a time, test at every step, and never add to code that doesn't work.
Let's start with the number of students:
int main() {
const int num_of_students;
cout << "How many students do you have in your class?" << endl;
cin >> num_of_students;
return(0);
}
Try to compile this, and you'll find that there's something wrong. Fix it and try constructing an array of int and filling it in. Once that's working, try an array of string. Small steps.
You realy should be using maps for this question, its makes the most sense. Here is code to read in the map from a file. After you have the map all the operations you need are already implemented in the STL. I realize you may need to use vector but I'd like to think you wouldn't be penalized for being clever and actually writing a proper solution.
#include <map>
#include <fstream>
#include <iostream>
using namespace std;
int main(){
map<string,string> data;
fstream fs("classroster.txt");
while(fs.good()){
string fname, lname, grade;
fs >> fname;
fs >> lname
fs >> grade;
fname += lname; //Concat Names to get full
if(grade == "A") //Check other grades as well.
data.emplace(fname,grade);
}
while(1){
string option;
std::cout << "Options:" << endl;
cin >> option;
//Your option selection code here
}
return 0;
}
EDIT:
maps are also sorted by key name so printing alphabetically is very easy, no sorting required.
for(auto& pairs : data)
cout << pairs.first << " " << pairs.second << endl;
I'm new to C++. I decided to not watch the next tutorial and put my skills to use, by making a funny Mind Reader application. I'm pleased with myself, however, even though I've ironed out most bugs, I still have one concerning the exit function. I read the C++ documentation for it, and I'm not sure what I did wrong. I did exit(0);. I have a very weird error, which is:
no match for call to '(std::string {aka std::basic_string<char>}) (int)
I have searched online, however I am still unaware of what the problem is. My error is on line 59 (marked in the code):
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
//declaring variables to be used later
string name;
string country;
int age;
//header goes below
cout << "#######################################";
" ############ MIND READER ############"
"#######################################\n\n";
//asks if the user would like to continue and in not, terminates
cout << "Would like you to have your mind read? Enter y for yes and n for no." << endl;
cout << "If you do not choose to proceed, this program will terminate." << endl;
string exitOrNot;
//receives user's input
cin >> exitOrNot;
//deals with input if it is 'y'
if (exitOrNot == "y"){
cout << "Okay, first you will need to sync your mind with this program. You will have to answer the following questions to synchronise.\n\n";
//asks questions
cout << "Firstly, please enter your full name, with correct capitalisation:\n\n";
cin >> name;
cout << "Now please enter the country you are in at the moment:\n\n";
cin >> country;
cout << "This will be the final question; please provide your age:\n\n";
cin >> age;
//asks the user to start the sync
cout << "There is enough information to start synchronisation. Enter p to start the sync...\n\n";
string proceed;
cin >> proceed;
//checks to see if to proceed and does so
if (proceed == "p"){
//provides results of mind read
cout << "Sync complete." << endl;
cout << "Your mind has been synced and read.\n\n";
cout << "However, due to too much interference, only limited data was aquired from your mind." << endl;
cout << "Here is what was read from your mind:\n\n";
//puts variables in sentence
cout << "Your name is " << name << " and you are " << age << " years old. You are based in " << country << "." << endl << "\n\n";
cout << "Thanks for using Mind Reader, have a nice day. Enter e to exit." << endl;
//terminates the program the program
string exit;
cin >> exit;
if (exit == "e"){
exit(0); // <------------- LINE 59
}
}
}
//terminates the program if the input is 'n'
if (exitOrNot == "n"){
exit(0);
}
return 0;
}
Thanks
The local variable exit shadows other identifiers from outer scopes with the same name.
To illustrate with a smaller example:
int main()
{
int i;
{
int i;
i = 0; // assign to the "nearest" i
// the other i cannot be reached from this scope
}
}
Since the only exit visible is an object of type std::string, the compiler sees exit(0) as a call to operator()(int) and throws a hissy fit when it doesn't find one among std::string members.
You can either qualify the name (std::exit(0);) or rename the variable. And since all of your code is in main you can simply say return 0; instead.
Try using return 0; or return EXIT_SUCCESS;. It's the exact same thing. Also, you can only input one word into a cin. Instead, use getline(cin, string name); If it still doesn't work, add a cin.ignore(); before your getline(cin, string name);, like this:
//stuff
string country;
cout << "Now please enter the country you are in at the moment:\n\n";
cin.ignore();
getline(cin, country);
//stuff
return 0;
The problem is arrising because you declared a standard keyword as the name of a local variable.
Now as the local variable is of type sting it is not able to take it as its value.
I am in the second phase of a project where I need to extend my program into a menu driven application to query the database I have on a .txt file. So, my trouble is that I cannot get my loop to be perpetual. It always terminates when it initializes from one option to the next. Here is the snippet of my code that is my int main:
int main ()
{
char Q,q;
char S,s;
char task;
string pathname;
string z;
int count=0;
cout << "Welcome to Jason Rodriguez's Library Database." << endl;
cout << "Please enter the name of the backup file: ";
cin >> pathname;
ifstream inFile(pathname.c_str());
while(!inFile.eof())
{
getline(inFile,z);
count++;
}
while (task != 'Q' || task != 'q') {
cout << count << " records loaded successfully." << endl;
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> task;
if ((task == 'Q')||(task =='q'))
{
cout << "Program will now terminate";
break;
}
else if ((task == 'S')||(task =='s'))
{
showAll (loadData (pathname));
cout << endl;
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> task;
}
}
}
I need to add two more options into the loop on top of these two but I figured I should get the first two working correctly first. The other two should be plug & chug after that. Basically what I was trying to do is say if the user enters Q or q, terminate the program. Else, if user hits S or s, activate showall function and after ward, go back to the original query. It isn't working though. Assistance is welcome and appreciated.
Menus almost always require loops - especially ones that require the user to enter the correct choice input. The most applicable one in a case like this is the while loop - but essentially, any other loop variant can be used.
UPDATE:
int main ()
{
char task;//this is the only char needed. Your other chars were redundant
string pathname;
string temp;//I changed z to temp to better reflect its purpose
int count=0;
cout << "Welcome to Jason Rodriguez's Library Database." << endl;
cout << "Please enter the name of the backup file: ";
cin >> pathname;
ifstream inFile(pathname.c_str());//this is potentially a problem in that you aren't verifying that the pathname is a valid one
//you did not check to see that your file was open, otherwise there is no way to tell that you successfully opened the file
if (inFile.is_open()) {
//while(!inFile.eof()) is a character by character read and comparison
//made your life easier by shortening it down to this - which ensures
//that a line is read. (Much faster and more readable)
while(getline(inFile,temp))
{
count++;
}
inFile.close();//always close a file after you've used it
//At this point the entire file has been read. So, this is where this message SHOULD be
cout << count << " records loaded successfully." << endl;
}
else {
//if there was an error opening the file (i.e. wrong path, or it simply does not exist), this will be displayed
cout << "There was a problem opening your file" << endl;
exit(0);//and the program will terminate
}
while (task != 'Q' || task != 'q') {
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> task;
if ((task == 'Q')||(task =='q'))
{
cout << "Program will now terminate";
break;
}
else if ((task == 'S')||(task =='s'))
{
string author;
//showAll (loadData (pathname));
cout << endl;
cout << "Search an Author" << endl;
cin >> author;//get the author name to search from the user
//write code to search an author here
}
}
}
There are a number of issues with the code that you posted which I will forgo for the sake of brevity. Hence, note the following:
Your code was printing the same message per option (except for quit). Of course it would appear that it didn't work. Each option is a different task. Print what each task does (similar to what I did).
You wish to search the file for an author, but you have not stored it. Look into a way of storing it that appeases your instructor.
It would be ideal for you to use switch in this case, considering the increasing complexity of your code.
Try breaking down each task into functions, and call them to make your main function readable. In fact, it is a good programming practice for your main function to be as small as possible.
And, as juanchopanza quite rightly pointed out: you have some fundamental issues with C++. Try doing some more exercises and do more examples from a good C++ book.