0

I am having trouble reading data from a file into a list in a class. It seems like an extra hexadecimal value is being picked up somewhere.

Data: (what I want output to look like) enter image description here

Output: (extra 0x4463c4 is randomly included) enter image description here

Here is a bit of code i think is relevant. Can anyone advise me of errors I may have made?

Where data is read into program from file (main):

struct filmType
{
     char number[6];
     char copy;
     char title[31];
     char rent_id[5];
     char rent_date[9];
     char return_date[9];
};


orderedList <filmType> orderedList;
    filmType newItem;

    //start of struct record
    filmFile.open("films.txt", ios::in);
    filmFile >> numFilm;
    filmFile.get();

    while (!filmFile.eof())
    {
         filmData.copy = filmFile.get();
         readString(filmFile, newItem.title,30);
         readString(filmFile, newItem.rent_id,4);
         readString(filmFile, newItem.rent_date,8);
         readString(filmFile, newItem.return_date,8);
         filmFile.get();

         orderedList.insert (newItem);

         readString(filmFile, filmData.number,5);
    }

orderedlist.insert function:(fills list in class)

void orderedList<elemType>::insert(const elemType& newItem)
{
     int index = length - 1;
     bool found = false;

     if (length == MAX_LIST)
         throw string ("List full - no insertion");

         // index of rear is current value of length

     while (! found && index >= 0)
        if (newItem < list[index])
        {
            list[index + 1] = list [index];  // move item down
            --index;
        }
        else
            found = true;

     list [index + 1] = newItem;  // insert new item
     ++length;
}

Orderedlist.display function: (outputs list to console)

void orderedList<elemType>::display() const
{
    int index;

    if (length == 0)
        throw string ("List empty");

    for (index = 0; index < length; ++ index)
        cout << list[index] << endl;
}

readString:

void readString (fstream & inFile, char * string, int length)
{
    inFile.get (string, length + 1);
}

Any help is appreciated, let me know if anything needs to be clarified or if more code from the program needs to be seen. Thanks!

darko
  • 2,438
  • 8
  • 42
  • 54
  • You don't think `readString` is relevant? – K-ballo Oct 17 '11 at 22:08
  • 2
    You obviously have a complex program, and you recognized that it was too complex to post in its entirety. Instead of posting bits of a big program, how about posting all of a smaller program? Please reduce your program to the smallest possible program that compiles, runs, and shows your error. See http://sscce.org for more information about this debugging technique. – Robᵩ Oct 17 '11 at 22:10
  • In the alternative, step through you program in a debugger. Stop after each file input operation and examine the data that was input. Where does your program first vary from you expection? – Robᵩ Oct 17 '11 at 22:13
  • 1
    It's not really obvious from the code, try reducing it and validating each step. UnitTest++ is a great framework for these sorts of projects. And for the love of all that is sacred, don't throw strings. Throw something that inherits from `std::exception`. `std::logic_error` or `std::runtime_error` are obvious candidates. – Tom Kerr Oct 17 '11 at 22:15

2 Answers2

0

You're passing structs objects to cout, which doesn't know how to display them. The hex values you get are your structs objects addresses.

Marc Plano-Lesay
  • 6,808
  • 10
  • 44
  • 75
  • 1
    If operator << was not overloaded the program would not even compile. Your assumption is wrong. – FailedDev Oct 17 '11 at 22:17
  • I thought overloading << addressed that problem. I did so in my header: ostream & operator << (ostream & out, const filmType & a) { out << a.number << " " << out << a.copy << " " << out << a.title << " " << out << a.rent_id << " " << out << a.rent_date << " " << out << a.return_date << endl; return out; } (sorry, how might I format code in comments?) – darko Oct 17 '11 at 22:17
  • Oh, I though the compiler would display memory address, like with pointers. Then the problem is probably in his implementation of `operator<<` – Marc Plano-Lesay Oct 17 '11 at 22:18
  • 1
    That's it. Remove all your `out` except the first. – Marc Plano-Lesay Oct 17 '11 at 22:19
  • @mwmnj Without knowing how filmType looks like we can't pinpoint your problem, however your problem is definitely located here. Check what you are printing, it seems to me you are printing the address of something. – FailedDev Oct 17 '11 at 22:20
  • You're welcome. Btw, you can display code with backquotes in comments. – Marc Plano-Lesay Oct 17 '11 at 22:21
0

End of File in C++

.eof() will not return true until after a read actually fails. Which means for the last loop:

while (!filmFile.eof())  //last read worked ok!  
{
     filmData.copy = filmFile.get();  //oh, reached end now.  read in nothing

Which means the rest of that loop is incorrect. Generally, the pattern is like this:

filmFile.open("films.txt", ios::in);
while (readString(filmFile, filmData.number,5)) {
    filmFile.get(filmData.copy)
    readString(filmFile, newItem.title,30);
    readString(filmFile, newItem.rent_id,4);
    readString(filmFile, newItem.rent_date,8);
    readString(filmFile, newItem.return_date,8);
    filmFile.get();

    if (filmFile) //make sure there weren't errors
        orderedList.insert (newItem);
};
fstream& readString (fstream & inFile, char * string, int length)
{
    return inFile.get (string, length + 1);
}

Which means as soon as the read fails (from eof), the while condition fails, and breaks out of the loop.

Community
  • 1
  • 1
Mooing Duck
  • 64,318
  • 19
  • 100
  • 158