-1

I'm trying to complete an assignment for my intro to C++ class and I've reached an impasse! The program is supposed to be a VHS Video Manager, in which the movies are stored in structures. The movies are obtained from a .txt file in the source folder and consist of the title of the movie, as well as the year. After reading in the text file, the initial output should look like this:

Initializing Video Collection:
What file should I use? movies.txt
A New Hope (1977)
Empire Strikes Back (1980)
Flight of the Navigator (1986)
Goonies (1985)
Last Crusade (1989)
Raiders of the Lost Ark (1981)
Return of the Jedi (1983)
Temple of Doom (1984)
War Games (1983)

The videos are stored in a structure that looks like this:

struct Video
{
    string title; //the name of the video
    int year; // the year the movie was released
    int stars; // a rating out of five stars - this will be zero until you set it
    bool watched; // starts as false until you watch the movie and flip it to true
};

It seems that I don't know how to read in my file correctly, so that the title and year are placed in their respective array locations. Here is the function that I have for this purpose:

void initialize(Video video_array[tapes_max], Video data)
{

    ifstream videofile;
    videofile.open("movies.txt");
    if(videofile.fail())
    {
        cout << "Could not open states file for reading!" << endl;
        exit(1);
    }
    for(int i = 0; i < tapes_max; i++)
    {
        getline(videofile, video_array[i].title);
    }

    videofile.close();
    for (int i = 0; i < tapes_max; i++)
    {
       cout << video_array[i].title << " " << video_array[i].year << endl;
    }

    cout << endl << endl;
}

Here is the link to the PDF that was assigned to me, maybe you guys can make better sense of it than I can? Thanks in advance for your help!

https://docs.google.com/open?id=0Bwr7dC-H4CCZUkkyUGNTRzRZdk0

midoriha_senpai
  • 177
  • 1
  • 16
  • 5
    So far, you've read the whole input line into a string. Now you need to _parse_ that string -- split into the `title` and `year` parts. Right? After that, you'd better convert year from string into an int. – Vlad Nov 16 '12 at 18:56
  • 1
    There is no function to put a line right into a struct, you have to know what it looks like, and then parse it accordingly. – SinisterMJ Nov 16 '12 at 18:57
  • 2
    You're about 1/3rd the way home. You have the data file opened, the lines read, and stuffed into a collection. Now you need to parse each line for the movie title name and year, storing appropriately in your structure. The rankings and watched-status are entirely up to you. – WhozCraig Nov 16 '12 at 18:57
  • What is the format of the movies.txt file? What does it look like? – Mooing Duck Nov 16 '12 at 19:01
  • The point is he currently has in the video_array[i].title both the movie name as well as the year, so you have to find that last (XXXX) and then get the year out of it. – SinisterMJ Nov 16 '12 at 19:04
  • @Vlad that really should be posted as an answer – Dan F Nov 16 '12 at 19:18
  • @Dan: you're right, just did it – Vlad Nov 16 '12 at 21:48

2 Answers2

2

So, you've read the input line into a string. Now, you need to split it into two parts: the title and the year. This is usually called parsing: extracting some information from a string.

I assume you didn't get a formal grammar (set of rules which defines your string format) as a part of your task, but it's quite easy to make a good guess: the line contains the title (possibly with spaces), followed with a space, opening parenthesis, a decimal representation of the release year, followed by a closing parenthesis.

Do you see how to parse it? A good choice would be scanning the string backwards:

  1. if the last character is not a closing parenthesis, complain about wrong format; otherwise, chop it off, you've done parsing the parenthesis.
  2. find the opening parenthesis; if there's no one, complain. you have to search from the end: the title can possibly contain parentheses on its own, so the opening parenthesis interesting to us must be the last one. store the text between the parentheses (be careful with indices!): it's going to be your year.
  3. parse the year into a number (atoi or the like, see this answer or Google for more details); if the parsing fails, the program must complain about wrong input format
  4. chop off the preceding space and complain if the space was not found
  5. the rest of the string must be the video title; check at least that it's not empty.

Enough for parsing, now your Video object has a title and a release year. The other two fields have for now the default values; however your program must be able to change them and possibly serialize them (a fancy word for saving the information into a file), so that the next time the user starts your program, the state of these fields is preserved.

This means perhaps that you should invent a format for your data on the disk, which contains all the four fields (the current .txt contains only two of them). And of course you need a parser for that format as well. I personally would use really simple format in your case: for example, just one field per line.

Welcome to the world of software development!

Community
  • 1
  • 1
Vlad
  • 35,022
  • 6
  • 77
  • 199
0

I think you should use boost::regex.
Here is a demo on how to process a line using regex:

#include <boost/regex.hpp>
#include <iostream>
#include <string>
#include <cstring>

int main()
{
  using namespace std;

  string line = "Hey Joe(1984) "; // an example line that you can read
  boost::smatch what;
  boost::regex e("(.*)\\(([0-9]+)\\).*"); // whatever comes before numbers in parentheses, is the title.

  if(boost::regex_match(line, what, e, boost::match_extra))
  {
    string title = what[1];
    int year = atoi(static_cast<string>(what[2]).c_str()); // perhaps there is a better code for this but it will do.
    cout<<"title: "<<title<<"\tyear: "<<year<<endl;
  }
  else
  {
    cout<<"No match"<<endl; // indicates a wrong line
  }
  return 0;
}

Just put this into a loop and you're done.

If you don't know how to use boost:

Install boost -- (on Mac, I installed boost with Macports)

Compiling line for me:

g++ -I/opt/local/include -L/opt/local/lib -lboost_regex-mt boost_regex.cpp
# for testing
./a.out 

For you it could be something similar on windows. (g++ -IC:\path\to\boost\includes -LC:\path\to\boost\libs -lboost_regex-something). On Windows I think you should look-up a dll file that is named something like "boost_regex.dll". You can find the dll in the lib directory of your boost installation.

Further info: Regex docs

Barney Szabolcs
  • 11,846
  • 12
  • 66
  • 91