Stuck on C++ code using Structure - c++

Currently I am stuck and not sure where to go from here...
I'm supposed to write a program that declares a struct to store the data for a player. Then declare an array of 10 components to store the data for 10 baseball players.
The program reads from a file and stores the data for ten baseball players, including player’s team, name of player, number of homeruns, batting average, and runs batted in.
The program prints out a menu (in a loop, so this can be done again and again) giving the user a choice to:
print out all users and statistics
print out the statistics for a specific player
print out all data for a specific team
update the data for a particular player (change one of the statistics)
Before the program terminates, give the user the option to store the data in an output file.
If anyone has ANY TIPS OR ADVICE I will be very grateful... I'm fairly new to coding in C++ and just stuck here... thank you in advance...
#include <iostream>
#include <fstream>
using namespace std;
struct BaseballID
{
string teamName, playerFirstName, playerLastName;
int homeRuns, rbi;
double batting_average;
};
int main()
{
BaseballID listofplayers[10];
ifstream infile;
infile.open("/users/AlecKleyer/Desktop/computer science term 2/BaseballStats.txt");
if (!infile)
{
cout << "Error opening file!";
return 0;
}
for (int j = 0; j < 10; j++) {
infile >> listofplayers[j].teamName >> listofplayers[j].playerFirstName >> listofplayers[j].playerLastName >>listofplayers[j].homeRuns >> listofplayers[j].rbi >> listofplayers[j].batting_average;
}
cout << "Please Type The Following Letter: ";
cout << "\n(A) For All Users and Stats";
cout << "\n(B) For A Specific Player";
cout << "\n(C) Print out for specific team";
cout << "\n(D) Update stats for a player";
char input = 0;
cin >> input;
if (input == 'A' || input == 'a') {
printInfoAll(*listofplayers[]);
}
if (input == 'B' || input == 'b') {
}
if (input == 'C' || input == 'c') {
}
if (input == 'D' || input == 'd') {
}
}
void printInfoAll(listofplayers1[])
{
for (int i = 0; i < 10; i++) {
cout << &listofplayers[i];
}
}

One thing you did right was making a function of printInfoAll (even if its buggy). Note this will not compile and there might be more errors.
#include <iostream>
#include <fstream>
using namespace std;
struct BaseballID
{
string teamName, playerFirstName, playerLastName;
int homeRuns, rbi;
double batting_average;
};
void printInfo(const BaseballID& id) {
cout << id.teamName << " " << id.playerFirstName // and so on!!!!
<< "\n"; // and a newline.
}
void printInfoAll(const BaseballID listofplayers1[]) // we need a type and a paramter
{
for (int i = 0; i < 10; i++) {
cout << printInfo(listofplayers[i]); // you
}
}
void printMenu() { // factor out the components in easy reusable parts.
cout << "Please Type The Following Letter: ";
cout << "\n(A) For All Users and Stats";
cout << "\n(B) For A Specific Player";
cout << "\n(C) Print out for specific team";
cout << "\n(D) Update stats for a player";
}
int main()
{
BaseballID listofplayers[10]; // consider using std::vector instead
// from here
ifstream infile;
infile.open("/users/AlecKleyer/Desktop/computer science term 2/BaseballStats.txt");
if (!infile.isOpen()) // I think the isOpen is needed.
{
cout << "Error opening file!";
return 0;
}
for (int j = 0; j < 10; j++) {
infile >> listofplayers[j].teamName >> listofplayers[j].playerFirstName >> listofplayers[j].playerLastName >>listofplayers[j].homeRuns >> listofplayers[j].rbi >> listofplayers[j].batting_average;
// hmm you trust your indata I don't check for errors here.
}
// to here should be a function, but then you need to restructure a bit more
printMenu();
char input = 0;
cin >> input;
switch(input) {
case 'A': case 'a':
printInfoAll(*listofplayers[]);
break;
case 'B': // and so on
// code for 'B' and 'b'
break;
....
default:
printMenu();
break;
}
// at this point you will find out you should have put it all in a loop.
return EXIT_SUCCESS;
}
The reason for adding const to the parameters is so that the user of the functions can see it promises not to change the values.

Related

Having an issue with my switch menu in a while loop

So I am working on a switch inside of a while loop. And it is not behaving properly. When I select 'l' and load the file it lets me select again, then when I try and press 'p' to print it, it just keeps looping over the selection prompt. I am pretty sure it is because choice != 'q', but don't know how to fix it.
Thank you for any help.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
//create a struct called Weather
struct Weather {
int month;
int date;
int high;
int avg;
int low;
double precip;
string event;
};
//function prototypes
int loadData(ifstream &file, Weather days[1000]);
void printData(Weather days[1000], int count);
int main() {
// declare variables
Weather days[1000];
ifstream inFile;
string checker;
char choice = '0';
int month = 0, count;
string path;
cout << "Welcome to the weather analyzer!" << endl;
while (choice != 'q') {
cout << "Would you like to (l)oad data, (p)rint data, (s)earch data, (o)rder the data, or (q)uit? ";
cin >> choice;
cout << endl;
switch (choice) {
case 'l':
// promt user for file path
cout << "Please enter the file path: ";
cin >> path;
// open the file
inFile.open(path);
// checks to see if file successfully opened and terminates if not
if (!inFile) {
cout << "Bad Path";
getchar();
getchar();
return 0;
}
loadData(inFile, days);
count = loadData(inFile, days);
break;
case 'p':
printData(days, count);
break;
case 's':
case 'o':
case 'q':
cout << "Good bye!";
break;
default:
cout << "Invalid option";
}
}
// Close file.
inFile.close();
// Pause and exit.
getchar();
getchar();
return 0;
}
//loading function
int loadData(ifstream &inFile, Weather days[1000]) {
string checker;
int month = 0;
int i; //i varaiable keeps track of how many lines there are for the print function
for (i = 0; !inFile.eof(); i++) {
inFile >> days[i].date; // gets date and checks if it is 2017 with if loop
if (days[i].date == 2017) {
getline(inFile, checker);
getline(inFile, checker);
inFile >> days[i].date; //gets correct date value
month++;//increments month counter
}
days[i].month = month;//gets and stores data from file into days
inFile >> days[i].high
>> days[i].avg
>> days[i].low
>> days[i].precip;
getline(inFile, days[i].event);
}
return i; //returns amount of days
}
// printing function
void printData(Weather days[1000], int count) {
for (int i = 0; i < count; i++) {
cout << days[i].month << " "
<< days[i].date << " "
<< days[i].high << " "
<< days[i].avg << " "
<< days[i].low << " "
<< days[i].precip << " "
<< days[i].event << " ";
cout << endl;
}
}
After reading the user input with cin, you probably want to flush the cin buffer:
cin.clear();
cin.ignore(INT_MAX);

Difficulty in a menu oriented program for C++

I am having an issue when trying to use a getline command where a user can enter in a movie and then add to the collection of movies (stored in "movies.txt")
My code is compiling, but it starts out with the 3rd case automatically. When I press "q" to quit that case, it reverts to the menu, yet when I try and write out the file or print the collection, no movie titles have been saved. Where I should go from here? I feel like I'm on the cusp of understanding this.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int ARRAY_SIZE = 200;
string movieTitle [ARRAY_SIZE];
int loadData (string pathname);
int writeData (string pathname);
int getTitle (string movieTitle[]);
void showAll (int count);
int main()
{
loadData("movies.txt");
char userInput;
string movieTitle[ARRAY_SIZE];
int count = getTitle(movieTitle);
bool endOfProgram = false;
while (endOfProgram ==false)
{
cout << "1. Read in Collection" << endl;
cout << "2. Print Collection" << endl;
cout << "3. Add a Movie to the Collection" << endl;
cout << "4. Write out Collection" << endl;
cout << "5. Quit the Program" <<endl;
cin >> userInput;
switch(userInput)
{
case('1'):
{
loadData("movies.txt");
break;
}
case('2'):
{
showAll(loadData("movies.txt"));
break;
}
case('3'):
{
cout << getTitle(movieTitle);
break;
}
case('4'):
{
cout <<"Write out Collection" << endl;
writeData("movies.txt");
break;
case('5'):
{
endOfProgram=true;
cout << "Have a nice day" <<endl;
break;
}
}
}
}
}
int loadData (string pathname)
{
int count = 0;
ifstream inFile;
inFile.open(pathname.c_str());
if (!inFile)
return -1;
else
{
while(!inFile.eof())
{
getline(inFile, movieTitle[count]);
count++;
}
}
return count;
}
int writeData (string pathname)
{
ofstream outfile;
outfile.open("movies.txt");
if(!outfile.is_open())
{
cout << "Cannot open movies.txt" << endl;
return -1;
}
outfile.close();
return 0;
}
void showAll (int count)
{
cout << "\n";
for (int i=0; i< count; i++)
{
cout << movieTitle[i] << endl;
}
cout << "\n";
}
int getTitle (string movieTitle[])
{
string movie;
int count = 0;
while(true)
{
cout <<"Enter Movie Titles (Type 'q' to quit)" <<endl;
cin >> movie;
if (movie == "q")
{
break;
}
movieTitle [count] = movie;
count++;
}
return count;
}
I believe cin reads until eol is found, i.e. the user presses return.
So look for integer in the userInput variable, and pass that to your switch statement
int nr = atoi(userInput.c_str())
switch(nr){
case 1:
case 2: etc ...
In your codes it is not clear why it directly goes to case '3'. It should wait for a user input first. Seems like something already available in buffer. Just put one cout statement in case '3': and check what it print. If possible put break point there and run the application in debug mode and check the value. Hope this will help you.
case('3'):
{
cout<<"Value of userInput is: "<<userInput<<endl;
cout << getTitle(movieTitle);
break;
}
Alternately you can add the below line of code just before cin like below
std::cin.clear();
cin >> userInput;
I recommend inputting an integer instead of a character for your input.
You will need to change the case values too:
int selection = 0;
//...
cin >> selection;
switch (selection)
{
case 1:
//...
}
You won't have to worry about characters in the buffer. The stream will fail if an integer is not read.

C++ how to restart the loop if user just presses enter or if the input is invalid?

I'll start by saying I have worked on this for 3 days now and this is only my second semester programming. I know this question is probably easy for most, but I really have very little experience.
The code I have written all works as intended except the invalid/blank entry validation. Anything I have found and tried just breaks other parts of the code or doesn't work at all.
Here are the instructions given in the homework for the part I am having issues with:
"Any invalid input for the menu will simply redisplay the menu.
Option 1 will prompt for a userName. An empty name will be ignored."
Here is my code. Any help is greatly appreciated.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<string> usernames;
void listMenu();
void addName();
void listNames();
void removeName();
int main()
{
char entry;
bool exit = false;
while (exit == false)
{
cout << "Choose from the following menu: \n";
listMenu();
cin >> entry;
if (entry == '\n')
{
listNames();
}
if (entry == '1')
{
addName();
}
else if (entry == '2')
{
listNames();
}
else if (entry == '3')
{
removeName();
}
else if (entry == 'x' || entry == 'X')
{
exit = true;
}
}
usernames.clear();
return 0;
}
void listMenu()
{
string menu[4] = { "1. Add a username","2. List all usernames","3. Delete a username","X. Exit" };
for (int i = 0; i < 4; i++) {
cout << menu[i] << endl;
}
}
void addName()
{
string name;
cout << "Enter a username: " << endl;
cin >> name;
usernames.push_back(name);
}
void listNames()
{
int n = 1;
cout << "**************\n";
for (auto& x : usernames)
{
cout << n <<". "<< x <<endl;
n++;
}
cout << "**************\n";
}
void removeName()
{
int x;
cout << "Which username would you like to remove?\n";
listNames;
cin >> x;
usernames.erase(usernames.begin()+x);
}
You can test your input and clear it if it's invalid. Using cin.fail, cin.clear and cin.ignore.
#include<iostream>
using namespace std;
bool cond;
int main() {
int n;
do {
cout << "Enter an integer number:";
cin >> n;
cond = cin.fail();
cin.clear();
cin.ignore(INT_MAX, '\n');
} while(cond);
return 0;
}

C++ user input to string array infinite loop

I'm trying to parse a user input string into an array. Example: user inputs "hello to you" array[0]="hello" array[1]="to" array[2]="you' After I prompt the user to input some words, the program seems to infinitely loop. I have also tried using a vector, so it may be my logic in another area. I'm very rusty when it comes to the C language, so please excuse my ignorance. Any help would be greatly appreciated!
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
struct FATNode;
struct FileNode;
class FileList;
class FAT
{
FATNode* head;
};
class FileList
{
FileNode* head;
//methods
public:
int createfile()
{
string word[2];
cout << "Please input file name, followed by file size: ";
int i = 0;
for (string input; cin >> input; i++)
word[i] = input;
for(i=0; i<2; i++)
cout << word[i] << ' ';
return 0;
}
};
struct FileNode
{
string filename;
int filesize;
FAT t1;
FileNode* next;
};
struct FATNode
{
int sectornumber;
FATNode* next;
};
main()
{
FileList myFileSystem;
char start;
int cmd;
bool cont = true;
while(cont == true)
{
cout << "Initializing disk.\n" << "To access menu, type 'Y'. To exit, type 'N': ";
cin >> start;
if(start == 'y' || start == 'Y')
{
cout << "What command would you like to execute on the disk?" << endl;
cout << "1. Format disk\n2. Create file\n3. Delete file\n";
cout << "4. List\n5. Read file\n6. Overwrite file\n7. Append to file\n8. Disk status\nSelection: ";
cin >> cmd;
switch(cmd)
{
case 1 :
break;
case 2 :
myFileSystem.createfile();
break;
default :
cout << "Invalid command" << endl;
}
}
else if(start == 'n' || start == 'N')
{
cont = false;
}
else
{
cout << "Invalid input." << endl;
}
}
}
Your loop condition is cin >> input. This expression returns cin, which can be implicitly converted into a boolean (http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool). However, cin only becomes false, if there's an error or if you have reached end of file (EOF). You can signal EOF by pressing Ctrl+D.
Note also, that you are using a fixed-size array to store information that you get from the user. That's bad, because if the user enters more than 2 words, the array word will overflow. That's undefined behaviour.
If you just want a file name, followed by a file size, why don't you just use:
std::string filename;
std::size_t filesize;
std::cin >> filename >> filesize;

Do While loop breaks after incorrect input?

I am trying to have a loop continue to prompt the user for an option. When I get a string of characters instead of an int, the program loops indefinitely. I have tried setting the variable result to NULL, clearing the input stream, and have enclosed in try{}catch blocks (not in this example). Can anyone explain to me why this is?
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int menu(string question, vector<string> options)
{
int result;
cout << question << endl;
for(int i = 0; i < options.size(); i++)
{
cout << '[' << i << ']' << options[i] << endl;
}
bool ans = false;
do
{
cin >> result;
cin.ignore(1000, 10);
if (result < options.size() )
{
ans = true;
}
else
{
cout << "You must enter a valid option." << endl;
result = NULL;
ans = false;
}
}
while(!ans);
return result;
}
int main()
{
string menuQuestion = "Welcome to my game. What would you like to do?";
vector<string> mainMenu;
mainMenu.push_back("Play Game");
mainMenu.push_back("Load Game");
mainMenu.push_back("About");
mainMenu.push_back("Exit");
int result = menu(menuQuestion, mainMenu);
cout << "You entered: " << result << endl;
return 0;
}
It looks like there is a random element here, since result is not initialized.
In any case, test cin directly
if ( cin && result < options.size() )
and reset it upon invalid input so it will again perform I/O operations
result = 0; // inappropriate to initialize an integer with NULL
cin.clear(); // reset cin to work again
cin.ignore(1000, '\n'); // use \n instead of ASCII code