Sorting strings from a text file.

EDIT: I am new to this forum, and forums in general, so if I broke any rules or there are things I can improve please do not hesitate to let me know!

I am currently working on a program that reads in movie information from a text file. So far, I can separate the title, directors, and year but the names of the actors are all still on one line.

I am trying to work out how to create an object for each title, alphabetize the actors within the specific title, and then sort the movies in alphabetical order. Each Title will be separated by a line of equals signs.

Text file example:

Lady and the Tramp (title)
1955 (date)
Directors: Clyde Geronimi Wilfred Jackson Hamilton Luske (can stay as is)
Peggy Lee (actor)
Barbara Luddy (actor)
Larry Roberts (actor)
==================== (separator)

I attempted using vectors and failed miserably and I am currently trying to work out a class to sort the data. The major hangup is how to read in the names to a separate array/vector for sorting. There are six total entries with varying numbers of actors, so setting something to a static value will not work, which is why I considered vectors. Any tips or help is appreciated!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  	/*
	1.  read in the Name, Release Date, the Directors and stars
  	2.  Sort the movies by Movie Name alphabetically,
  	2.  Sort the stars alphabetically,
  	3.  Print the Movie Name, Release Date, Directors
        4.  Print the list of stars (alphabetically)
	*/
	//could use arrays/vectors for movie title, directors, and stars?


#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <vector>
//these are included for testing different approaches
using namespace std;

class Movie {
	string title;
	int year;
	string directors;
	string actors;
	string separator;
};

int main() {
	//variables
	const int SIZE = 50;
	int count = 0;
	string names[SIZE];


	ifstream disneyFile; //input file
	disneyFile.open("disneyMovies.txt"); //input file location
	//if file cannot open, error message shows and program exits
	if(!disneyFile) {
		cout << "Unable to open file." << endl;
		exit(1);
	}
	else { //test to make sure file is working
		cout << "Reading file now...\n" << endl;
	}


// 1. Read in the Name, Release Date, Directors, and Stars
	//while counter variable is less than the size of the array, write each
          line to names[count]
	while (count < SIZE) {
		getline(disneyFile,names[count]);
		count++;
	}

//testing for reading and writing data into array
	for(int i = 0; i < SIZE; i++) {
		cout << names[i] << endl;
	}


	disneyFile.close(); //close when done reading file


}
Last edited on
Welcome! Your post is nicely formatted and the explanation is clear, so you're above average :)

If you're not sure how many actors will be listed per movie, then yes, this is a good candidate for a vector.

For example, if this is my file:

This Is A Title
1984
Directors: Names of People Not Really Formatted
John Smith
Jane Smith
Jone Doe
Jane Doe
====================

and I know that it will always be in that order (title, date, directors line, {line for each actor}), then that makes parsing it relatively easy.

I commented the code so you can start to understand what's happening:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <string>
#include <fstream>
#include <algorithm> // std::sort
#include <vector>

using namespace std;

class Movie {
  public:
	string title;
	int year;
	string directors;
	vector<string> actors;
};


int main()
{
	ifstream fin("movies.txt");
	
	if (!fin)
	{
		cout << "Could not open movies.txt\n";
		return 1;
	}
	
	while (true)
	{
		Movie movie;
		
		// get the easy stuff (title, year, directors)
		
		if (!getline(fin, movie.title)) // getline returns false if it didn't read in another line successfully
		{
			std::cout << "<end of file reached, no more movies>\n";
			break; // exit outer loop, we're done reading the file.
		}
		fin >> movie.year; // >> operator will get next word in file (in this case, the year) and put it into the year variable
		getline(fin, movie.directors);
		
		//
		// now we need be a little bit smarter with getting the actors
		// because there can be varying amounts per movie
		//
		while (true)
		{
			std::string actor;
			if (getline(fin, actor))
			{
				if (actor == "====================") // make sure there isn't trailing spaces...
				{
					// We're done parsing that movie.
					// sort the movie's actors
					// See: http://www.cplusplus.com/reference/algorithm/sort/
					sort(movie.actors.begin(), movie.actors.end());
					break; // exit inner loop
				}
				else // add another actor to the movie's vector of actors (strings)
				{
					movie.actors.push_back(actor);
				}
			}
			else
			{
				std::cout << "<No more valid input in file, assuming end>\n";
				// sort the movie's actors
				sort(movie.actors.begin(), movie.actors.end());
				break; // exit inner loop
			}
		}
		
		//
		// We now have a valid Movie, print it here
		//
		///// TODO
	}
}


I used the "======..." separator to delimit different movies, and this also assumes every movie has at least one actor (this isn't always the case!).

I know this might be a lot at once... basically, as you parse each line, you need to figure out how to store the actors's names.
so you have a vector<string> actors, initially empty.
Every time you parse an actor from your file, you can add to this vector by using push_back: movie.actors.push_back(actor);
Last edited on
Topic archived. No new replies allowed.