Trouble with arrays and structs from input file - c++

I am working on this problem for a college course and I'm unsure why it isn't working. I thought I had everything setup correctly, but when I try running the program the file won't open on the first attempt at inputting the file name and when I input it again I get an "Exception Thrown" error in the "xmemory" part that I have no idea what any of it means.
The input file that the program is taking data from is just a text file with the following data:
201742 Sponge Bob 82.6
201701 Patrick Star 14.1
201753 Squidward Tentacles 85.43
201744 Sandy Squirrel 75.61
201700 Plankton Plank 100.0
The final output of the program should display the highest and lowest grade with the students first and last name, the average score, and the number of students tested. Any help would be much appreciated.
// Zane Richards
// Lab 10 Q2
// 4/6/2020
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <fstream>
using namespace std;
struct student {
int ID;
string firstName;
string lastName;
float grade;
};
void maxGradeFunc(struct student* s, int size)
{
float maxGrade = 0;
string firstName, lastName;
for (int i = 0; i < size; ++i)
{
if (s[i].grade > maxGrade)
{
maxGrade = s[i].grade;
firstName = s[i].firstName;
lastName = s[i].lastName;
}
}
cout << "Maximum grade is " << maxGrade << endl;
cout << "The name of the student with the grade is: " << firstName << " " << lastName << endl;
}
void minGradeFunc(struct student* s, int size)
{
float minGrade = 999;
string firstName, lastName;
for (int i = 0; i < size; ++i)
{
if (s[i].grade < minGrade)
{
minGrade = s[i].grade;
firstName = s[i].firstName;
lastName = s[i].lastName;
}
}
cout << "Maximum grade is " << minGrade << endl;
cout << "The name of the student with the grade is: " << firstName << " " << lastName << endl;
}
void avgGradeFunc(struct student* s, int size)
{
float sum = 0;
for (int i = 0; i < size; ++i)
{
sum += s[i].grade;
}
float avg = sum / size;
cout << "Avearge grade is " << avg << endl;
cout << "The total number of students are: " << sum << " students" << endl;
}
int main()
{
ifstream inFile;
string fileName = "";
struct student s[5];
int ID;
string firstName, lastName;
float grade;
int i = 0;
cout << "Please enter the input file name: "; //File is named "Student.txt"
cin >> fileName;
while (!inFile.is_open()) {
cout << "Sorry, the file did not open. \nTry again, or type \"cancel\" to quit: ";
cin >> fileName;
if (fileName == "cancel") {
cout << "Cancelling..." << endl;
break;
}
else {
inFile.open(fileName);
}
}
while (inFile.is_open()) {
inFile >> ID;
s[i].ID = ID;
inFile >> firstName;
s[i].firstName = firstName;
inFile >> lastName;
s[i].lastName = lastName;
inFile >> grade;
s[i].grade = grade;
i++;
}
maxGradeFunc(s, 5);
minGradeFunc(s, 5);
avgGradeFunc(s, 5);
return 0;
}
Here is the error code I'm getting: https://i.stack.imgur.com/i35Oq.png

Figured out the issue, deleted the code that allowed for multiple attempts, and changed it to just open the file and that fixed it. Thanks for the help everyone, much appreciated!

Related

Why is the data in the "addtocart()" function not written into the file ? c++

In this program I'm trying to add data about customers in a file. However, for some reason when I open the file I can only see the data from the "newcustomer()" function. Can somebody tell me the reason for this please.
Here's the related part of my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct cartitem{
string name;
int num_of_copies;
float price;};
int i;
int ci=0;
fstream customersdata;
void newcustomer(fstream &customersdata, string cname){
string arrtime;
customersdata << "Name: " << cname << '\n';
string order = cname+"order";
customersdata << order <<'\n';}
void addtocart(fstream &customersdata, string cname){
ci++;
string bname;
cout << "enter book name \n" ; cin >> bname;
int num_of_copies;
cout << "enter number of copies to add to cart \n" ; cin >> num_of_copies;
string order = cname+"order";
cartitem x;
x.name = bname;
x.num_of_copies=num_of_copies;
if(customersdata.is_open()){
string b;
while (getline(customersdata,b)){
if (b.find(order, 0) != string::npos){
size_t pos;
pos = b.find(order, 0);
customersdata.seekp(pos+ci);
customersdata << "item" << ci << ": " << x.name << " num of copies: " << x.num_of_copies <<'\n';}}}
else { cout << "unable to open file\n";}}
int main(){
string cname;
customersdata.open("customersdata.txt", ios::out | ios::in);
cout << "enter customer name\n"; cin >> cname;
newcustomer(customersdata,cname);
addtocart(customersdata,cname);
customersdata.close();
string filename = "customersdata.txt";
system(filename.c_str());}
that's what the file looks like if I run a test code for a person named james

Issue regarding functions returning a string

The program for my class needs to return the average score, the high score with first and last name as well as the low score. I get an error for the functions that find the names for the high and low score and I'm not sure what the issue is.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
float highestVal(float highScore, float score);
float lowestVal(float lowScore, float score);
string highFirstFun(float highScore, float score, string firstNameHigh);
string highLastFun(float highScore, float score, string lastNameHigh);
string lowFirstFun(float lowScore, float score, string firstNameLow);
string lowLastFun(float lowScore, float score, string lastNameLow);
int main() {
ifstream inFile;
string fileName = "", firstName = "", lastName = "";
float score, average;
float highScore = 0;
float lowScore = 100;
float studentNum = 0;
float sum = 0;
int i;
string highFirst = "", highLast = "";
string lowFirst = "" , lowLast = "";
cout << "Please enter the input file name: ";
cin >> fileName;
inFile.open(fileName);
while (!inFile.is_open()) {
cout << "Sorry, the file did not open. \nTry again, or type \"cancel\" to quit: ";
cin >> fileName;
if (fileName == "cancel") {
cout << "Cancelling..." << endl;
break;
}
else {
inFile.open(fileName);
}
}
if (inFile.is_open()) {
cout << "The scores are as follows: \n";
while (!inFile.eof()) {
inFile >> firstName >> lastName >> score;
cout << firstName << " " << lastName << " scored " << score << endl;
sum += score;
studentNum++;
highScore = highestVal(highScore, score);
lowScore = lowestVal(lowScore, score);
highFirst = highFirstFun(highScore, score, firstName);
highLast = highLastFun(highScore, score, lastName);
lowFirst = lowFirstFun(highScore, score, firstName);
lowLast = lowLastFun(highScore, score, lastName);
}
average = (sum / studentNum);
cout << "There are " << studentNum << " students with an average grade of " << average << endl;
cout << "The high score was: " << highScore << " from " << highFirst << " " << highLast << endl;
cout << "The low score was: " << lowScore << " from " << lowFirst << " " << lowLast << endl;
inFile.close();
}
return 0;
}
float highestVal(float highScore, float score)
{
if (score > highScore) {
highScore = score;
}
return (highScore);
}
float lowestVal(float lowScore, float score)
{
if (score < lowScore) {
lowScore = score;
}
return (lowScore);
}
string highFirstFun(float highScore, float score, string firstNameHigh)
{
if (score > highScore) {
return (firstNameHigh);
}
}
string highLastFun(float highScore, float score, string lastNameHigh)
{
if (score > highScore) {
return (lastNameHigh);
}
}
string lowFirstFun(float lowScore, float score, string firstNameLow)
{
if (score < lowScore) {
return (firstNameLow);
}
}
string lowLastFun(float lowScore, float score, string lastNameLow)
{
if (score < lowScore) {
return (lastNameLow);
}
}
Here is the Text File that it is pulling from called "Scores.txt":
John Smith 99.0
Sarah Johnson 85.0
Jim Robinson 70.0
Mary Anderson 100.0
Michael Jackson 92.0
Any help would be much appreciated!
A function that has a return type must always return that type. The function
string highFirstFun(float highScore, float score, string firstNameHigh);
For example must always return a string when it is called. The issue is the definition of your function
string highFirstFun(float highScore, float score, string firstNameHigh)
{
if (score > highScore) {
return (firstNameHigh);
}
}
highFirstFun() Will only return a string if (and only if) score is higher than highScore. Well, what will happen if score is not higher than highScore? This will be a problem for the function because it's not designed to do anything if a condition like this happens, so the compiler will complain about it. This applies to all your functions. To make them work, you'll have to find a way to make them return a string is all scenarios.

My function don't take over the variable value from other function

I have a program to create a phone book in a file. Some of my functions don't work or don't work properly.
user.h
#pragma once
#include <string>
#include <vector>
using namespace std;
class User
{private:
string firstname, lastname, country, city, street;
string phone;
public:
string prefix;
void ReadAllUsers(User[], int&);
void SaveUser(User, int&);
void SaveToFile(const User[], int);
void AddName(User[], int&);
void ListAllUsers(const User[], int&);
void Prefix(User, int);
void ChangePhone(User[], int&);
void Help();
void DeleteUser(User[], int&);
bool Search(string x)
{
return (phone.find(x) != string::npos);
}
};
user.cpp
#include "User.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#pragma warning(disable:4996)
using namespace std;
const string PHONEBOOK_FILENAME = "phonebook.txt";
void User::Help()
{cout<<"\nWELCOME TO THE APPLICATION!\n";
cout<<"Press 0 to display on the screen all records that are saved in the file(phonebook.txt)\n";
cout<<"Press 1 to add 1 or more new record(s) in file(phonebook.txt)\n";
cout<<"Press 2 to delete permanently a record from file(phonebook.txt)\n";
cout<<"Press 3 to sort users from file(phonebook.txt) by name and display them on the screen\n";
cout<<"Press 4 to edit a user phone number and save it after in file(phonebook.txt)\n";
cout<<"Press 5 for help\n";
cout<<"Press 6 to exit the application\n";
}
void User::ReadAllUsers(User people[], int &num_people)
{
ifstream f;
f.open(PHONEBOOK_FILENAME.c_str());
if (f.fail())
{
cout << "Unable to open file " << endl;
return ;
}
int i = 0;
while (!f.eof() && i < 100)
{ getline(f, people[i].firstname);
getline(f, people[i].lastname);
getline(f, people[i].phone);
getline(f, people[i].country);
getline(f, people[i].city);
getline(f, people[i].street);
i++;
}
num_people = i;
f.close();
}
//Add country prefix to the phone number
void User::Prefix(User person, int num_people)
{string filecountry;
ifstream f;
f.open("prefix.txt");
{
while (getline(f, filecountry))
{
if (person.country == filecountry )
{
f.ignore();//next line
f >> person.prefix;
}
}
f.close();
}
}
void User::SaveUser(User person, int &num_people)
{
ofstream f(PHONEBOOK_FILENAME.c_str(), ios::app ) ;
if (f.fail())
cout << "Unable to open file " << endl;
else
f << person.firstname << " " << person.lastname << " " << person.country << " " << person.city << " " << person.street << " " << person.prefix << "-" << person.phone << endl;
cout << "\nThe user was added\n";
}
//Save data after a modification or after a user delete
void User::SaveToFile(const User people[], int num_people)
{ofstream f;
f.open(PHONEBOOK_FILENAME.c_str());
for(int i = 0; i < num_people; i++)
{
f << people[i].firstname << " " << people[i].lastname << " " << people[i].country << " " << people[i].city << " " << people[i].street << " " << people[i].prefix << " " << people[i].phone << endl;
}
}
// Read user data from the keyboard, add a new contact to the array
void User::AddName(User people[],int &num_people)
{User person;
cout <<"Enter the user's first name: ";
cin >> person.firstname;
cout <<"Enter the user's last name: ";
cin >> person.lastname;
cout <<"Enter the user's country: ";
cin >> person.country;
cout <<"Enter the user's city: ";
cin >> person.city;
cout <<"Enter the user's street: ";
cin >> person.street;
cout <<"Enter the user's phone number: ";
cin >> person.phone;
Prefix(person, num_people);
cout <<"The prefix is " << person.prefix;
for(int i = 0; i < num_people; i++)
{
if( i + 1 == num_people)
people[num_people] = person;
}
SaveUser(person, num_people);
num_people++;
}
// Ask the for person's name to change, find the person in the array and
// change it to the new phone number. Then save the new data to file by
// calling SaveToFile.
void User::ChangePhone(User people[], int &num_people)
{
User person;
int count;
cout <<"Enter name to change: ";
cin >> person.firstname;
for(count = 0; count < num_people; count++)
{
if(people[count].Search(person.firstname))
{ cout <<endl<< people[count].firstname<<endl;
cout <<"Current number"<<people[count].phone;
cout << "\nNew number: ";
cin >> people[count].phone;
SaveToFile(people,num_people);
cout <<"\n\nNew number Saved.";
return;
}
}
if(count = num_people)
cout <<"\nName not found.\n";
}
void User::DeleteUser(User people[], int &num_people)
{string phone;
int count = 0;
ifstream f;
f.open("phonebook.txt");
cout << "Input the phone of user that you want to delete ";
cin >> phone;
for(count = 0; count < num_people; count++)
{
if(people[count].Search(phone))
{ cout <<endl<< people[count].phone<<endl;
people[count].firstname = people[count].lastname = people[count].phone = people[count].country = people[count].city = people[count].street = " ";
}
SaveToFile(people,num_people);
cout <<"\n\nUser deleted.";
return;}
f.close();
}
The function Prefix()(this is to add automatically a country prefix for phone number, this is read from a file) is working but the value of person.prefix it's not taken by SaveUser(), so the value is not wrote in file.The function SaveToFile() save all users on single line in file.
And functions ChangePhone() and DeleteUser don't working.
The problem is that void User::Prefix(User person, int num_people) takes person by value, so it makes a copy of the person, changes the copy, then the copy goes away when the function ends. The original was never changed.
Instead, you want:
void User::Prefix(User & person, int num_people)
To have a reference to the person specified, which will be affected by the changes you make inside the function.
Also, I recommend you change your saveuser to be:
void User::SaveUser(User const & person, int &num_people) const
just to avoid making extra copies of the User object, but it's not incorrect the way you currently have it, I don't think.

Adding user input to a method and putting the results into a file (C++)

Any help would be appreciated. All I'm trying to do is ask for user input, do some calculations and print the results in a file. I thought that my code was correct but when I run my program, I get nothing. Here is my code. Not looking for an answer, just for any tips to lead me in the right direction. Thanks.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class Employee{
private:
int id;
int job_class;
int years_service;
int Ed;
float salary;
public:
void getData(ifstream&);
void computation(int job_class, int years_service, int Ed);
void printout(ofstream&);
};
void Employee::getData(ifstream& infile){
infile >> id >> job_class >> years_service >> Ed;
}
void Employee::computation(int job_class, int years_service, int Ed){
int basePay = 800;
float jobresult, Yearresult, Edresult;
if(job_class == 1){
jobresult = .05;
}
if(job_class == 2){
jobresult = .10;
}
if(job_class == 3){
jobresult = .15;
}
if(years_service <= 10){
Yearresult =.05;
}
if(years_service > 10){
Yearresult = .05;
}
if(Ed == 1){
Edresult = .00;
}
if(Ed == 2){
Edresult = .05;
}
if(Ed == 3){
Edresult = .12;
}
if(Ed == 4){
Edresult = .20;
}
salary = basePay + jobresult + Yearresult + Edresult;
//cout << salary;
}
void Employee::printout(ofstream& outfile){
outfile << "ID: " << "Salary " << endl;
outfile << id << salary;
}
int main(){
Employee emp; //created an Employee object
string input;
int id;
int job_class;
int years_service;
int Ed;
int basepay = 800;
cout << "Enter id" << endl;
cin >> id;
cout << "Enter job_class" << endl;
cin >> job_class;
cout << "Enter years of service" << endl;
cin >> years_service;
cout << "Enter education" << endl;
cin >> Ed;
ifstream inFile;
ofstream outFile;
//getline(cin, input);
inFile.open("example.txt");
outFile.open("examplee.txt");
//inFile.open(input);
std::string r = std::to_string(id); //converted id to string
inFile.open(r);
getline(cin, r);
std::string s = std::to_string(years_service);
inFile.open(s);
getline(cin, s);
std::string t = std::to_string(years_service);
inFile.open(t);
getline(cin, t);
std::string u = std::to_string(Ed);
inFile.open(u);
getline(cin, u);
if(inFile.is_open()){
emp.getData(inFile);
inFile.close();
}
outFile.open(r);
if(outFile.is_open()){
emp.computation(job_class, years_service, Ed);
float sal = basepay + job_class + years_service + Ed;
outFile << "ID " << "Salary " << endl;
outFile << id << sal;
outFile.close();
return 0;
}
}
What exactly are you trying to do with things like this?
std::string r = std::to_string(id); //converted id to string
inFile.open(r); /*Opens a file whose name is <id> ???*/
getline(cin, r); /*Overwrites the contents of r and does nothing??? */
Your entire program is fairly confusing. My best guess as to the (main) problem is that you aren't writing anything to inFile at all. Those 12 lines after outFile.open("examplee.txt") seem like they are trying to accomplish the following:
inFile << id << ' ' << job_class << ' ' << years_service << ' ' << ED << '\n';
Also, although I'm guessing this is for debugging purposes, but many of your methods do nothing or are unused. For example, you use emp.computation(job_class, years, ED) but after that you don't use emp at all in any way. And the three lines after that seem to mimic the behavior of Employee::computation and Employee::printout.
I suggest you carefully consider the specific steps you're trying to take, then think about the purpose of methods like getline and fstream::open, and ask yourself "Does this accomplish the task I had in mind?". Because I'm really struggling to understand what you are trying to do when I read this code.

i need to create array on the heap aby to hold a specific number set by the user

hey guys new to this site looking some help for my final project i having to create a project that takes car data saves it to the heap and has a bunch of error checking not all the way done but getting there. but i cant grasp the heap and how to input it correctly into my code here is what i have. and it has to be under 175 lines and i still have to have it ask user if they want to write to a new file or existing. thanks ahead once again question is how do i create array on the heap able to hold the number of vech specified buy user.
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
class carData4
{
public:
void setYear(int& year);
void setMake(string make);
void setModel(string);
void setMileage(int& mileage);
void setName(string name);
void setNumber(string number);
int getYear(){ return itsYear; }
string getMake(){ return itsMake; }
string getModel(){ return itsModel; }
int getMileage(){ return itsMileage; }
string getName(){ return itsName; }
string getNumber(){ return itsNumber; }
private:;
int itsYear;
string itsMake;
string itsModel;
int itsMileage;
string itsName;
string itsNumber;
};
void carData4::setYear(int & year)
{
do
{
cout << "Enter the cars Year from 1910 and 2014:\n ";
cin >> year;
itsYear = year;
if (year < 1910 || year > 2014)
cout << "INVALID! please enter a correct year! ";
} while (year < 1910 || year > 2014);
}
void carData4::setMake(string make)
{
cout << "Enter the cars make:\n\n";
cin >> make;
itsMake = make;
}
void carData4::setModel(string model)
{
cout << "Enter the cars model:\n\n";
cin >> model;
itsModel = model;
}
void carData4::setMileage(int & mileage)
{
do{
cout << "Enter the cars mileage:\n\n";
cin >> mileage;
itsMileage = mileage;
}
while (mileage <0 || mileage >10000000);
cout << "NOPE enter within 0 and million miles.\n\n";
cin >> mileage;
itsMileage = mileage;
}
void carData4::setName(string name)
{
cout << "Enter your name :";
cin >> name;
itsName = name;
}
void carData4::setNumber(string number)
{
cout << "Enter Your phone number (XXX)XXX-XXXX:";
cin >> number;
itsNumber = number;
}
int main()
{
carData4 car1;
int year, mileage, numCars, ;
string make, model, name, number;
cout << "How many vehicles are to be added to inventory?.\n\n";
cin >> numCars;
for (int i = 1; i < numCars; i++){
car1.setYear(year);
car1.setMake(make);
car1.setModel(model);
car1.setMileage(mileage);
car1.setName(name);
car1.setNumber(number);
cout << car1.getYear() << "\t" << car1.getMake() << "\t " << car1.getModel()
<< "\t" << car1.getMileage() << "\t " << car1.getName() << "\t " << car1.getNumber() << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
i add some is this correct????????????????
int main()
{
carData4 car1; // *car1=new carData4[numCars];
int year,mileage,numCars;
double *cars;
string make,model,name,number;
cout << "How many vehicles are to be added to inventory?.\n\n";
cin >>numCars;
cars = new double [numCars];
for (int i=1; i<numCars;i++){
car1.setYear(year);
car1.setMake(make);
car1.setModel(model);
car1.setMileage(mileage);
car1.setName(name);
car1.setNumber(number);
cout << car1.getYear() << "\t" << car1.getMake() << "\t " << car1.getModel()
<< "\t" << car1.getMileage() << "\t " << car1.getName() << "\t " << car1.getNumber() <<endl;
delete [] cars;
}
system("PAUSE");
return EXIT_SUCCESS;
}
The best way to have dynamic storage for your use case would be to use a vector, like so:
std::cout << "How many vehicles are to be added to inventory?.\n\n";
std::size_t n;
std::cin >> n;
std::vector<carData4> cars ( n );
//gives you:
//cars[0] ... cars[ n-1 ]
http://en.cppreference.com/w/cpp/container/vector
To dynamically allocate an array based on user input:
unsigned int array_capacity;
cout << "Enter array capacity: ";
cin >> array_capacity;
int * my_array = new int[array_capacity];
Remember to delete the array using delete [] my_array;.
Edit 1: using Car class
CarData4 * my_cars = new CarData4[numCars];