-4

I thought I had this completely worked out, but it isn't actually writing anything to the file. It is opening the employeesOut.txt file but not writing anything. Any guesses? I'm getting the error

Here is the input file as requested.

123,John,Brown,125 Prarie Street,Staunton,IL,62088
124,Matt,Larson,126 Hudson Road,Edwardsville,IL,62025
125,Joe,Baratta,1542 Elizabeth Road,Highland,IL,62088
126,Kristin,Killebrew,123 Prewitt Drive,Alton,IL,62026
127,Tyrone,Meyer,street,999 Orchard Lane,Livingston,62088

libc++abi.dylib: terminating with uncaught exception of type std::invalid_argument: stoi: no conversion (lldb)

I believe the error is within my main.cpp, so here that is.

#include <iostream>
#include <string>
#include <fstream>
#include "Employee.h"

using namespace std;

bool openFileForReading(ifstream& fin, const string& filename);
bool openFileForWriting(ofstream& fout, const string& filename);

int readFromFile(ifstream& in, Employee empArray[]);

void writeToFile(ofstream& out, const Employee empArray[], const int numberofEmployees);

int main(){

ifstream fin;
ofstream fout;

if(!openFileForReading(fin, "employeesIn.txt")) {
    cerr << "Error opening employeesIn.txt for reading." << endl;
    exit(1);
}

if(!openFileForWriting(fout, "employeesOut.txt")) {
    cerr << "Error opeing employeesOut.txt for writing." << endl;
    exit(1);
}

Employee employeeArray[50];

int employeeCount = readFromFile(fin, employeeArray);

fin.close();

writeToFile(fout, employeeArray, employeeCount);

fout.close();

cout << "Program successful." << endl << endl;


return 0;
}

bool openFileForReading(ifstream& fin, const string& filename) {
fin.open("employeesIn.txt");

return (fin.is_open());

}

bool openFileForWriting(ofstream& fout, const string& filename) {
fout.open("employeesOut.txt");

return (fout.is_open());

}

int readFromFile(ifstream& in, Employee empArray[]) {
int temp = 0;
string eidText;
string first;
string last;
string street;
string city;
string state;
string zipcode;

while(!in.eof()) {
    getline(in, eidText, ',');
    getline(in, first, ',');
    getline(in, last, ',');
    getline(in, street, ',');
    getline(in, city, ',');
    getline(in, state, ',');
    getline(in, zipcode, ',');

    empArray[temp].setEid(stoi(eidText));
    empArray[temp].setName(first, last);
    empArray[temp].setAddress(street, city, state, zipcode);

    temp++;
}

return temp;
}

void writeToFile(ofstream& out, const Employee empArray[], const int numberOfEmployees) {

for (int i = 0; i < numberOfEmployees; i++){
    out << "Employee Record: " << empArray[i].getEid()
    << endl
    << "Name: " << empArray[i].getName()
    << endl
    << "Home Address: " << empArray[i].getAddress() 
    << endl
    << endl;
}

}
MatthewTingle
  • 355
  • 2
  • 3
  • 12

1 Answers1

2

Your initial problem is solved by changing your getline(in, zipcode, ','); line to getline(in, zipcode, '\n');, since this will make getline end on the linebreak character. The error is generated when stoi is given 'Matt' as an argument.

However, your readFromFile function is receiving a copy of your array, and so the changes it makes aren't moved back into your main() function (since you're returning the count, not the array).

Since passing an array of references is messy, try instead using a std::vector (after #includeing <vector>) to group your individual employees. If Employee.H specifies a parameter-less constructor or no constructor (and you have a default constructor from your compiler), then

std::vector<Employee> employeeVector;
void readFromFile(ifstream& in, std::vector<Employee> &empVec);

void readFromFile(ifstream& in, std::vector<Employee> &empVec) {
// int temp = 0; unneeded.
string eidText;
...
string zipcode;

while(!in.eof()) {
    getline(in, eidText, ',');
    ...
    getline(in, zipcode, '\n');

    Employee tempEmp();
    tempEmp.setEid(stoi(eidText));
    ...
    empVec.push_back(tempEmp);

    // temp++; no longer need this
    }
} 

might be a better option. Even if the constructor is horribly complicated, it's still likely this would be simpler than arrays of references (you'd have to change the Employee tempEmp(); line though. Incidentally, if this complains and won't compile, I probably hit the MVP error - remove the ()s and you'll be fine.

Edit: Since you've been instructed to use an array of Employees, you can choose to return the array, if you wish, or alternatively passing it by pointer should be legal. This would require that you iterate through by moving the pointer along the array in a similar manner to your original code. I've left the vector approach above, since I think it's cleaner, but since you can't use it, you can choose from the two alternatives (return array, pass pointer instead of object). My guess is you're supposed to opt for the pointer, since this now appears to be a homework-style problem.

In that case, you can use

int main() {
...
Employee* empPtr = employeeArray;
...
}

void readFromFile(ifstream& in, Employee* empPtr) {
    string eidText;
    ...
    string zipcode;

    while(!in.eof()) {
        getline(in, eidText, ',');
        ...
        getline(in, zipcode, '\n');

        (*empPtr).setEid(stoi(eidText));
        ...

        empPtr++;
        }
    } 
chrisb2244
  • 2,940
  • 22
  • 44
  • I need the comma to parse through my input file, I've added the file above. And when I try passing by reference I only get errors :/ – MatthewTingle Sep 05 '14 at 18:35
  • If you remove the comma (only from zipcode, not from the others), getline will stop at the linebreak character. What errors does passing by reference give you? – chrisb2244 Sep 05 '14 at 18:38
  • I get empArray declared as array of references of type 'Employee &' – MatthewTingle Sep 05 '14 at 18:42
  • I also get an error on this line int employeeCount = readFromFile(fin, employeeArray); No matching function for call to 'readFromFile' – MatthewTingle Sep 05 '14 at 18:43
  • my problem could be on this line empArray[temp].setEid(stoi(eidText)); – MatthewTingle Sep 05 '14 at 18:43
  • I'm guessing in your header Employee.H you have a class with each `Employee` storing one value of each of these fields, which is nice, but the error you're getting with an array of references is iirc generally a pain. Perhaps you could use a std::vector instead of an array? The other error is just that you changed to a reference in some places and not others. – chrisb2244 Sep 05 '14 at 18:47
  • The instructions say to use an array :/ and yes I do have a class Employee.H and Employee.cpp – MatthewTingle Sep 05 '14 at 18:59
  • Pretty sure your runtime error originally posted is coming from the comma in the zipcode line. It's taking the eid of the next line and adding it to the zipcode, then reading 'Matt' as the next eid, which can't be made to an int. – chrisb2244 Sep 05 '14 at 19:00
  • Yes, when I step into that line, it says eidText is read as Matt when it should be read as 124 – MatthewTingle Sep 05 '14 at 19:05
  • I've changed it to getline(in, zipcode); and now it says the eidText is "" – MatthewTingle Sep 05 '14 at 19:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60725/discussion-between-chrisb2244-and-matthewtingle). – chrisb2244 Sep 05 '14 at 19:13