Justin
Justin

Reputation: 33

Avoiding the use of eof in this case

I have posted the following code where I am reading from an input file -- storing information in a structure -- and then writing to an output file. I know that the eof function is not safe and hence one must use the getline function to check whether the end of file has been detected or not; however, in this particular code, I have not been able to use the getline function and hence has finally relied on the eof function. Hence, can you please suggest an alternative to the eof function or let me know how I can use the getline function when I am trying to initialize an array of structures . I have used two asterisk symbols to indicate where I want to use the getline function.

#include <iostream>
#include <fstream>

using namespace std;
//student structure
struct student
{
  char name[30];
  char course[15];
  int age;
  float GPA;
};

ifstream inFile;
ofstream outFile;

student getData();
void writeData(student writeStudent);
void openFile();

int main (void)
{
  const int noOfStudents = 3; // Total no of students
  openFile(); // opening input and output files

  student students[noOfStudents]; // array of students

  // Reading the data from the file and populating the array
  for(int i = 0; i < noOfStudents; i++)
  {
        if (!inFile.eof()) // ** This where I am trying to use a getline function.
            students[i] = getData();
        else
            break ;
  }


  for(int i = 0; i < noOfStudents; i++)
    writeData(students[i]);

  // Closing the input and output files
  inFile.close ( ) ;
  outFile.close ( ) ;

}

void openFile()
{
  inFile.open("input.txt", ios::in);
  inFile.seekg(0L, ios::beg);
  outFile.open("output.txt", ios::out | ios::app);
  outFile.seekp(0L, ios::end);

  if(!inFile || !outFile)
  {
    cout << "Error in opening the file" << endl;
    exit(1);
  }

}

student getData()
 {
  student tempStudent;
  // temp variables for reading the data from file

  char tempAge[2];
  char tempGPA[5];

  // Reading a line from the file and assigning to the variables
  inFile.getline(tempStudent.name, '\n');
  inFile.getline(tempStudent.course, '\n');
  inFile.getline(tempAge, '\n');

  tempStudent.age = atoi(tempAge);

  inFile.getline(tempGPA, '\n');
  tempStudent.GPA = atof(tempGPA);
  // Returning the tempStudent structure
  return tempStudent;
 }

void writeData(student writeStudent)
 {
  outFile << writeStudent.name << endl;
  outFile << writeStudent.course << endl;
  outFile << writeStudent.age << endl;
  outFile << writeStudent.GPA << endl;
 }

Upvotes: 3

Views: 1747

Answers (2)

You want to write an operator>> for your student type. Something like:

std::istream& operator>>(std::istream& in, student& s) {
  in >> s.age; // etc.
  return in;
}

Which then allows you to write:

int studentNo = 0;
students[maxStudents];
while (studentNo < maxStudents && (in >> students[studentNo]))
  ++studentNo;

Upvotes: 3

nims
nims

Reputation: 3871

Why not write this way?

instead of

inFile.getline(tempStudent.name, '\n');
inFile.getline(tempStudent.course, '\n');
inFile.getline(tempAge, '\n');

You may

while(inFile.getline(tempStudent.name, '\n'))
{
    inFile.getline(tempStudent.course, '\n');
    inFile.getline(tempAge, '\n');
    //do stuffs
}

Upvotes: 0

Related Questions