Reading in a file causes a seg fault

I'm writing a program to store a library of tv shows. I'm trying to store the tv shows in an external data file that will be read into the program on startup and placed in an array. I can get the program to write the file after entering the information but when I try to have the program read in the data I get a seg fault. Any idea where I'm going wrong?

I have set up classes for this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//Constructor to read data from a file.
library::library(char filename[])
{
  int i=0;

  ifstream fin;
  fin.open(filename);

  if(fin)
  {
    while(!fin.eof())
    {
      list[i].readfile(fin);
      ++i;
    }
    fin.close();
    numshows=i;
  }
  else
    numshows=0;
}


This constructor calls the following function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Read tv show information from an external file.
int show::readfile(ifstream &fin)
{
  fin.get(title,209,'#');
  fin.get();
  fin.get(genre,16,'#');
  fin.get();
  fin.get(channel,4,'#');
  fin.get();
  fin.get(time,21,'#');
  fin.get();
  fin.get(website,31,'#');
  fin.get();
  fin.get(keywords,201,'#');
  fin.get();
  fin.get(description,101,'#');
  fin.get();
  return 0;
}


If the default constructor is called the program works find, but if the constructor to open the file and read in data stored there is called I get a Seg Fault. Any ideas?
Are all the C strings long enough to contain the data? channel in particular looks suspiciously short.
Is list long enough for any value of i?
Last edited on
Whatever list[] is, you are reading too many records.

Also, you are using global variables? (Don't do that.)

Is there a reason your lines are terminated with '#' ?


Fixes:
- use const when possible
- don't check for ifstream::eof() -- check against ifstream::good() instead. (I think this is why your program is failing -- if some error occurs, EOF will never be set.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Constructor to read data from a file.
library::library(const char filename[])
{
  int i=0;

  ifstream fin(filename);
  while(fin.good())
  {
    list[i].readfile(fin);
    ++i;
  }
  fin.close();
  numshows=i;
}


Your data file appears to be formatted something like:

Big Trouble In Little China#
Action-Fantasy#
10#
1:39#
www.imdb.com/title/tt0090728/#
John Carpenter,Kurt Russell,Kim Cattrall,Dennis Dun#
Truck driver and friends get involved with magic kung-fu demons#

I recommend that you switch to using std::strings in a sequence container such as std::vector, std::deque, or std::list, and that your file simply be a line-by-line list of shows.

Big Trouble In Little China
Action-Fantasy
10
1:39
http://www.imdb.com/title/tt0090728/
John Carpenter, Kurt Russell, Kim Cattrall, Dennis Dun
Truck driver and friends get involved with magic kung-fu demons

Now, all you need to do is provide your class with an input operator to read such data:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
istream& operator >> ( istream& ins, show& s )
{
  getline( ins, s.title );
  getline( ins, s.genre );
  getline( ins, s.channel );
  getline( ins, s.time );
  getline( ins, s.website );
  getline( ins, s.keywords );
  getline( ins, s.description );

  // this next line is optional -- if your input file has a blank line following
  // each show's data, this instruction will skip that line. Be sure to #include <limits>
  ins.ignore( numeric_limits <streamsize> ::max(), '\n' );

  return ins;
}

Now, for each show in the library, just read it:
1
2
3
4
5
6
7
8
9
10
11
12
//Constructor to read data from a file.
library::library(const char filename[])
{
  ifstream fin(filename);
  show s;
  while(fin >> s)
  {
    list.push_back( s );
  }
  fin.close();
  numshows=list.size();
}


Lastly, I recommend that you move the stuff to read the library out of the constructor into its own function. The constructor can then call that function.
1
2
3
4
5
6
7
8
9
library::library(const char filename[])
{
  load(filename);
}

void library::load(const char filename[])
{
  ...
}

Hope this helps.
Topic archived. No new replies allowed.