1

Hi I am having an issue with fstream variable. my movie class can't read info from the a text file:

here is the output is produces:

-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460
-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460
-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460
-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460
-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460
-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460
-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460
-858993460 Ì -858993460 -858993460 -9.25596e+061 -858993460 -858993460

and it SHOULD produce:

 110 8.3 2005 275523 A 140 Batman begins
 123 8.2 1965 45515 W 132 For a Few Dollars More
 181 8.1 1946 17648 R 172 The Best Years of Our Lives
 30 8.6 1946 103101 D 130 it's a Wonderful Life
 77 8.3 1952 56368 C 103 Singin' in the Rain
 88 8.3 1995 245089 A 177 Braveheart
 45 8.5 2001 185124 C 122 Amelie
 48 8.5 1962 80746 V 216 Lawrence of Arabia

and input text is:

 110 8.3 2005 275523 A 140 Batman begins
 123 8.2 1965 45515 W 132 For a Few Dollars More
 181 8.1 1946 17648 R 172 The Best Years of Our Lives
 30 8.6 1946 103101 D 130 it's a Wonderful Life
 77 8.3 1952 56368 C 103 Singin' in the Rain
 88 8.3 1995 245089 A 177 Braveheart
 45 8.5 2001 185124 C 122 Amelie
 48 8.5 1962 80746 V 216 Lawrence of Arabia
 -1

At this point I am having a hard time understanding why it's doing that. I am using MS VS2008.

here is the code:

#include "movieType.h"
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
movieType movie[9];
ifstream inFile("movie1.txt");

int i =0;

bool notDone=true;
while (notDone) 
{ 
    if (movie[i++].readMovieInfo(inFile)== false)
        notDone=false;    
}

for (int i=0;i<8;++i)
{
    movie[i].printMovieInfo("printList.txt");
}

return 0;
}

and the class specification

#include <string>
//include preprocessor directive to give access to string operations

class movieType
{
public:
    movieType();
    //Function: Class constructor
    //Precondition: none
    //Postcondition: instance variable initialized

    ~movieType();
    //Function: class destructor
    //Precondition: object has been initialized
    //Postcondition: memory allocated to class object freed up

    bool readMovieInfo(std::ifstream&);
    //Function: reads one movie at one time from a file
    //Precondition: object has been initialized
    //Postcondition: return false if the rank is <1 else return true

    void printMovieInfo(char*);
    //Function:prints one movie at a time to a file
    //Precondition: object has been initialized
    //Postcondition: none

    char getGenre();
    //Function: returns the movie genre
    //Precondition:object has been initialized
    //Postcondition: none

    int getRank();
    //Function: returns the movie rank
    //Precondition: object has been initialized
    //Postcondition: none

    bool operator>=(movieType) const;
    //Function: overload operator for '<=' for use in heap
    //Precondition: object has been initialized
    //Postcondition:none

    bool operator>(movieType) const;
    //Function: overload operator for '<' for use in heap
    //Precondition: object has been initialized
    //Postcondition:none

private:
    int rank; //movie ranking
    double weight; //calculated wieght for ranking
    int year; //year the movie was released
    int votes; //number of votes 
    char genre; //movie genre
    int length; //movie length in minute
    std::string name; //the name of the movie

};

and the class implementation:

#include "movieType.h"
//preprocessor directive gives access to movieType class
#include <fstream>
//preprocessor directive gives access fstream operations
#include <string>
//preprocessor directive gives access string operations

using namespace std;
// make fstream and string operations available without calling class std


movieType::movieType()
{
}

movieType::~movieType()
{
}

bool movieType::readMovieInfo(ifstream& inFile)
{
    inFile>>rank>>weight>>year>>votes>>genre>>length;
    getline(inFile,name);

    if (rank < 1)
        return false;
    else
        return true;
}

void movieType::printMovieInfo(char* outFileName)
{
std::ofstream outFile;
if(!outFile.is_open()) 
    outFile.open(outFileName, std::ios::app);
outFile<<name<<" "<<year<<" "<<genre<<" "<<length<<" "<<rank;
outFile<<" "<<weight<<" "<<year<<" "<<votes<<std::endl;

}
int movieType::getRank()
{
return rank;
}

char movieType::getGenre()
{
return genre;
}

bool movieType::operator >=(movieType other) const
{
if (rank >= other.rank)
    return true;
else
    return false;
}

bool movieType::operator >(movieType other) const
{
if (rank > other.rank)
    return true;
else
    return false;
} 
user1561949
  • 211
  • 7
  • 16
  • I created a text file with your "SHOULD produce" example, tested the code, and got the correct results. Please show **exactly** what the text file looks like, as it is different than the code you show under "SHOULD produce". (Also, you should always check that *all* reads and writes where performed correctly, as the problem is that your stream is failing somewhere probably). – Jesse Good Aug 26 '12 at 23:11
  • I am pretty new to c++. How would you check that all read and writes were performed correctly? – user1561949 Aug 26 '12 at 23:20
  • I've linked to a good writeup in my response. – Alexander Gessler Aug 26 '12 at 23:21
  • @jesseGood, I ran my prgm again and I get the same results as I have posted. I am curious on how you can run the same program and get the correct output. – user1561949 Aug 26 '12 at 23:25
  • @user1561949: See my answer and let me know if my assumption is incorrect. I suspect that file path is wrong. – Jesse Good Aug 26 '12 at 23:27
  • @Jesse Good: Since I started using fstream, I have always include the input text file in the same folder as main.cpp and it always worked. and I did the same thing here. How do I fix the file path? – user1561949 Aug 26 '12 at 23:33
  • @user1561949: Stuff like that gets OS specific. Look into [SetCurrentDirectory](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365530%28v=vs.85%29.aspx) and [GetCurrentDirectory](http://msdn.microsoft.com/en-us/library/windows/desktop/aa364934%28v=vs.85%29.aspx) and don't forget to include `windows.h`. Also, make sure that you just didn't misspell the file name, etc. – Jesse Good Aug 26 '12 at 23:39

2 Answers2

1

The problem in your code is the following line:

ifstream inFile("movie1.txt");

Basically, you never checked that the file was opened successfully.

Try, the following, and tell me what it outputs:

if (!inFile)
{
    std::cout << "Could not open file" << std::endl;
    return 1;
}

I bet that it tells you the file could not be opened.

Also, to check that the read were successful, do:

if(!(inFile>>rank>>weight>>year>>votes>>genre>>length))
{
     // Something went wrong
}

However, it might be better to break that up a bit.

Jesse Good
  • 50,901
  • 14
  • 124
  • 166
  • :) you won the bet! The file could not be opened. I am in a bind, how can i open it then it the file can't be opened? – user1561949 Aug 26 '12 at 23:28
  • @user1561949: The easiest way is to specify the full path, i.e. `c:/mydirectory/blah/movie1.txt` or if you know the relative path example: `debug/movie1.txt`. – Jesse Good Aug 26 '12 at 23:32
  • here is what I wrote, but I still can't open the file:
     ifstream inFile("C:/Documents and Settings/Administrator/My Documents/Visual Studio 2008/Projects/131part1/131part1/movie1.txt") 
    – user1561949 Aug 26 '12 at 23:55
  • @user1561949: Okay, to figure out the problem, check the [errno](http://msdn.microsoft.com/en-us/library/t3ayayh1%28v=vs.80%29.aspx) value, see [here](http://stackoverflow.com/questions/503878/how-to-know-what-the-errno-means) for an example. – Jesse Good Aug 26 '12 at 23:56
  • Good: I had made a stupid mistake. I had saved the input file as: movie1.txt.txt Thanks a lot for the help! – user1561949 Aug 27 '12 at 00:23
0

The most likely case is that stream reading fails, in which case all the movieType instances will go uninitialized. You should be checking the stream for errors and handle them appropriately, i.e. if (inFile.fail()) { ... } or just if (!inFile).

So basically you're printing uninitialized (i.e. random) memory.

The IOStream operators in C++ don't usually throw exceptions, it is absolutely crucial to do manual error checking.

See this response for a good writeup of the topic.

Community
  • 1
  • 1
Alexander Gessler
  • 45,603
  • 7
  • 82
  • 122