views:

254

answers:

3

I’m getting system error when I try to compile the code below on Visual C++ 2008 Express. What I’m trying to do is to initialize array of objects with data read from file. I think there is something wrong inside the while loop, because when I initialize these objects manually without the while loop it seems to work. Here is the code and text file:

#include <iostream>
#include <string>
#include "Book.h"

using namespace std;            

int main()
{
    const int arraySize = 3;
    int indexOfArray = 0;
    Book bookList[arraySize];
    double tempPrice;//temporary stores price
    string tempStr;//temporary stores author, title


    fstream fileIn( "books.txt" );

     while ( !fileIn.eof( ))
        {
     getline(fileIn,tempStr);
     bookList[indexOfArray].setAuthor(tempStr);

     getline(fileIn,tempStr);
     bookList[indexOfArray].setTitle(tempStr);

     fileIn >> tempPrice;
     bookList[indexOfArray].setPrice(tempPrice);

     if ( indexOfArray < arraySize )//shifting array index while not exceeding array size
      indexOfArray++;
        }

    fileIn.close();
return 0;
}

and the text file:

Author1
Book1
23.99
Author2
Book2
10.99
Autho3
Book3
14.56
A: 

The key must be in the contents of

#include "Book.h"

I copy-pasted your code, and replaced the #include with my assumption of what class Book might look like:

class Book
{
    std::string auth;
    std::string title;
    double price;
public:
    void setAuthor(std::string& str)
    {
        auth = str;
    }

    void setTitle(std::string& t) 
    {
        title = t;
    }

    void setPrice(double d)
    {
        d = price;
    }
};

and it compiled. Perhaps you could share your Book.h, or look there for any problems? Start with some simple definition from Book (like above) and begin readding code until you've found the lines that cause the problem. Its a crude method of figuring out the issue, but sometimes its the most direct way.

Doug T.
This is interesting, because as I mentioned it work if I initialize array manually.
Mike55
+4  A: 

It looks like you are trying to write to bookList[3] in the loop. You will loop through three times filling your array incrementing indexOfArray each time. This will leave indexOfArray at 3 -- your condition as it is written will allow indexOfAray to be incremented to 3. Then if you have a newline after the "14.56" in your data file you will loop one more time and attempt to pass an empty string to bookList[indexOfArray].setAuthor() leading to a segfault since indexOfArray is past the end of the array.

I would suggest ditching the hard-coded array and using a std::vector instead. At the start of each loop just use push_back() to add a new book to the end of the vector and then use back() to access the new element in the array.

Brett Hall
good catch. +1.
Doug T.
I rearranged the while loop and used fileIn.ignore() to discard the end of line after reading double . We haven’t learned vectors so far so I try to stick to the material covered in lectures. In the future I will definitely try to use vector as you suggested.
Mike55
+2  A: 

There's another run-time error in your code: You don't read an entire line with the call to fileIn >> tempPrice;. The next call to getline() will read to the end of the line, so you'll get an empty string when you're expecting an author.

You're then off by one line in your text file, and you try to convert a title into a double. That make the fstream signal an error, and after that, you're in trouble.

Brett's right, a vector with push_back is a better solution here.

Brett also correctly pointed out that you could run into errors if your file has extra lines. You can fix that by checking if you successfully read from the file:

if(fileIn >> tempPrice)
{
    bookList[indexOfArray].setPrice(tempPrice);
}
else
{
    break;
}

if(!getline(fileIn,tempStr))
{
    break;
}
Alex McCarthy