Search code examples
c++filepass-by-referencefileinputstream

Odd output when passing file stream by reference


In the code below, I am need to read the following from a data file:

Dean DeFino     88  98  99
Sally Johnson   78  89  82
Bill Benny      75  79  81
Thomas Billows  78  84  89 

However, I get this output:

Dean DeFino           88        98        99
hnson   78  89        82-1850860984     32742
        0         0        28
         0-413051128        48
-1608528832     32767-415228472
0    -49089-1024065536   6406657
-512190696        48     18048
     32767         0         0
0-1850766544     32742-520043854
0        48-517861416        48
-1608527569     32767-520043904
0     32767-520041858        48
-1564475392    -49089         0
        48-1850766544     32742
-514484708        48     26100
         0-1608527632     32767
`-1608528304     32767-310120049
0        48         0         0
-1608527592     32767-1608527584
        48-520056170        48
`-1850862392     32742-1608528432
     32742 479434334         0
   7491161         0        30
a         0-1608528048     32767
H<@0-1024065536   6406657-1398731262
f 673193995 5371330921477443664
DB(         0         0-1850860160
        48-515832000        48
0      2027         1-520053849
0     32742-1608527968     32767
-1850860160     32742 479434334
         0-1850860160     32742
         6         0-1850860928
        48         6         0
[-310357908        48         0
        48-520056170        48
-310356040        48-1608527984
     32742 725871085         0
  11341735         0        45
0         0-1608527600     32767
H<@0-310281904        48-1850766920
     32767-1850767776     32742
         0         0-1850860808
         0-515832000        48
@@           786         1         0
        48-1608527520     32767
-1850860808     32742 725871085
         0-1850860808     32742
          1     32767-517860984
0         1-310305400        48

It appears that only the first line and a half are read correctly. Given the code below, I do not see where the issue is. Any thoughts?

#include <fstream>
#include <iostream>
#include <iomanip>
using namespace std;

const int NAMESIZE = 15;
const int MAXRECORDS = 50;
struct Grades                           
{
    char name[NAMESIZE + 1];
    int test1;
    int test2;
    int final;

};

typedef Grades gradeType[MAXRECORDS];

void readIt(ifstream&, gradeType, const int);

int main()

{
    ifstream indata;
    indata.open("graderoll.dat");               
    gradeType studentRecord;

    if (!indata)
    {
        cout << "Error opening file. \n";
        cout << "It may not exist where indicated" << endl;
        return 1;
    }

    readIt(indata, studentRecord, MAXRECORDS);


    for (int count = 0; count < MAXRECORDS; count++)
    {
        cout << studentRecord[count].name << setw(10)
             << studentRecord[count].test1
             << setw(10) << studentRecord[count].test2;
        cout << setw(10) << studentRecord[count].final << endl;
    }

    indata.close();

    return 0;
}

void readIt(ifstream& inData, gradeType gradeRec, const int max)

{
    int total = 0;

    inData.get(gradeRec[total].name, NAMESIZE);
    while (inData)
    {
        inData >> gradeRec[total].test1;
        inData >> gradeRec[total].test2;
        inData >> gradeRec[total].final;

        total++;     // add one to total

        if (!inData.eof())
            inData.get(gradeRec[total].name, NAMESIZE);
    }

}

Thanks!


Solution

  • When the while loop is being read, there is no code that consumes the end of line, so one the program encounters the end of the line, it skips the rest of the file and the loop terminates. The weird output on the screen is a result of outputting an empty array of 49 garbage values (since MAXRECORDS = 50). Make a variable called numRead or something similar and set it equal to the number of lines you would like to read. Put that as the end condition in the for loop. Then in the while loop, place inData.ignore(NUMSIZE, '\n'); before where you read the name. So:

    while (inData)
    {
        inData >> gradeRec[total].test1;
        inData >> gradeRec[total].test2;
        inData >> gradeRec[total].final;
    
        total++;     // add one to total
    
        inData.ignore(NUMSIZE, '\n');
        inData.get(gradeRec[total].name, NAMESIZE);
    }
    

    inData.ignore(NUMSIZE, '\n'); will effectively tell the program to ignore the next 15 characters or until a newline escape sequence is encountered. This will allow the file to be read properly.