tags:

views:

77

answers:

3

As part of a larger assignment I have to create a method in a class that can read five lines of data then put that data into a dynamically created object. I am not sure how to go about getting the five lines of data separately into the object. The code should help to explain better but it does not work as desired. If someone can spot my mistakes please let me know. If you can help me it would be greatly appreciated. Also every five lines read I create a new object, until no lines are left. How would I know if any lines are left? Once again any help would be appreciated thank - you for your time.

    inline void readFromFile(const string& fileName){

        string title;
        string category;
        unsigned int runningTime;
        unsigned int yearOfRelease;
        double price;

        ifstream myReadFile;
        myReadFile.open(fileName);

        while( myReadFile )
        {
            myReadFile>>title;
            myReadFile >> category;
            myReadFile >> runningTime;
            myReadFile >> yearOfRelease;
            myReadFile >> price;

            v.push_back(new DVD(title,category,runningTime,yearOfRelease,price));
        }

        myReadFile.close();

        for(unsigned int i = 0; i < v.size(); i++){

            cout << *v.at(i) << endl;

        }

    }
+2  A: 

The problem is that operator >> with a string only reads one word (not a line).

You need to use the std::getline() function.

       std::getline( myReadFile, title);
       std::getline( myReadFile, category);
       std::getline( myReadFile, runningTime);
       std::getline( myReadFile, yearOfRelease);
       std::getline( myReadFile, price);

For convenience you should write an operator >> for DVD

std::istream& operator>>(std::istream& str, DVD& data)
{
    // Read data into data here
    return str;
}

Now your loop becomes a lot easier to write:

std::copy(std::istream_iterator<DVD>(myReadFile),
          std::istream_iterator<DVD>(),
          std::back_inserter(v)
         );
Martin York
This is what I have so far. Its true that it may be easier but my experience with c++ is very limited so I am trying to keep it as basic as possible. I made the first few changes, but now the file is not being read, and the data is not being displayed. Excuse me for my lack of knowledge in c++, but i am trying my best to learn. What changes do suggest I should make within the code.
Delanoy
@Delanoy: As Martin suggested, you should use `getline` instead of `>>` for strings (`title` and `category` in your case). The rest of your fields are numeric values and you can continue to use `>>` for them.
casablanca
@casablanca: @Dalanoy: Normally I would agree with casablanca and suggest using operator >>. But the file format clearly states that a record is five lines long. Therefore you should try and guarantee that you read exactly five lines. If you use the >> operator trailing spaces may be left on the last line. This could be a problem when reading the next object. Thus I would read the five lines into objects. Then I would convert each line into the appropriate type (probably with a boost::lexical_cast<> or a second choice std::stringstream)
Martin York
A: 

This is what I have now, the file is still not being read. I am at a lost of what to do.

inline void readFromFile(const string& fileName){

            string title;
            string category;
            unsigned int runningTime;
            unsigned int yearOfRelease;
            double price;

            ifstream myReadFile;
            myReadFile.open(fileName);

            while( ! myReadFile.eof() )
            {
                getline( myReadFile, title);
                getline( myReadFile, category);
                myReadFile >> runningTime;
                myReadFile >> yearOfRelease;
                myReadFile >> price;

                v.push_back(new DVD(title,category,runningTime,yearOfRelease,price));
            }

            myReadFile.close();

            for(unsigned int i = 0; i < v.size(); i++){

                cout << *v.at(i) << endl;

            }

        }
Delanoy
A: 

I am slightly confused by your usage of getline(). Try getting the data by calling getline() on the myReadFile variable. This uses a character array. So one possible way of rewriting the code may be as given below:

PS: Please note that your filename correctly delimits the slashes (\) while creating the string.

void readFromFile(const string& fileName){
            char title[80];
            char category[80];
            unsigned int runningTime;
            unsigned int yearOfRelease;
            double price;

            ifstream myReadFile;
            myReadFile.open(fileName.c_str());

            while( ! myReadFile.eof() )
            {
                myReadFile.getline( title, 80);
                myReadFile.getline( category, 80);
                myReadFile >> runningTime;
                myReadFile >> yearOfRelease;
                myReadFile >> price;

                v.push_back(new DVD(title,category,runningTime,yearOfRelease,price));
            }

            myReadFile.close();

            for(unsigned int i = 0; i < v.size(); i++){

                cout << *v.at(i) << endl;

            }

        }
Jughead
There is a getline() that use strings, thus you don't need to specify a limit on the line size. Also what happens if there are trailing spaces on the last line after the price?
Martin York
Jughead
I got it to work, thanks everyone for the help!
Delanoy