Hi.
I'm new in C++ and I need your help. I've got a structure and file in .csv format. It looks like this:

Twelve Monkeys;Sci-Fi / Thriller;USA;1995;129;Terry Gilliam;MUSIC;Bruce Willis, Madeleine Stowe, Brad Pitt;
American Gangster;Drama;USA;2007;157;Ridley Scott;Marc Streitenfeld;Denzel Washington, Russell Crowe;
Star Wars: Episode VI - Return of the Jedi;Sci-Fi / Fantasy / Action;USA;1983;134;Richard Marquand;John Williams;Mark Hamill, Harrison Ford;
Gladiator;Action / Drama / Historical;USA / GB;2000;149;Ridley Scott;Hans Zimmer;Russell Crowe;

I need to know how to search in names of movies and then get entirely line as a movie profile and some filter that can write every movie with entered value like year or genre.

I've got this so far: :D

#include <iostream>
#include <string>
#include <vector>
#include <fstream>

using namespace std;

int choose;

struct t_film																
{ 
  string name;
  string nameEng;
  string genre;
  string country;
  string year;
  string duration;
  string director;
  string music;
  string cast;
};
char loadFilm() 
{
	ifstream inFile;

	t_film film;

	vector <t_film> myData;													

	string line;
	int cnt = 0;

	inFile.open("in.txt");
	if (inFile.is_open()) 
	{
		
		while(!inFile.eof())												
		{
			getline(inFile, line, ';');									
            
			if (cnt == 0)														
			{
				film.name = line;
				cnt++;
			}

			else if (cnt == 1)													
			{
				film.nameEng = line;
				cnt++;
			}

			
			else if (cnt == 2)													
			{
				film.genre = line;
				cnt++;
			}

			else if (cnt == 3)													
			{
				film.country = line;
				cnt++;
			}

			else if (cnt == 4)													
			{
				film.year = line;
				cnt++;
			}

			else if (cnt == 5)													
			{
				film.duration = line;
				cnt++;
			}

			else if (cnt == 6)													
			{
				film.director = line;
				cnt++;
			}

			else if (cnt == 7)													
			{
				film.music = line;
				cnt++;
			}
			
			else																 
			{
				film.cast = line;
				myData.push_back(film);										
				
				cnt = 0;																			
			}

        }
    }
    else {
      cerr << "error." << endl;
    }

    inFile.close();
	
	switch(choose)
	{
	case 1: for(unsigned int i = 0; i < myData.size(); i++)							
		{
			
			cout << myData[i].name << endl;
		
		}
		break;

	case 2:
		for(unsigned int i = 0; i < myData.size(); i++)							
		{
			
			cout << myData[i].nameEng << endl;
			
		}
		break;
		
	default: cout << "unknown\n";
	}

	cout << endl;
	return 0;
}

I really appreciate your advice and help. Thank You.

Recommended Answers

All 6 Replies

Something doesn't match up here. You have 9 fields in your struct, but there are only 8 fields in your records. Why do you have 2 "name" fields?

Once you've straightened that out, test it again then post a better description of your problem; as I'm afraid I have no idea what you are asking.

How are you going to handle the leading numbers, like 1., 2., 3., etc., and the spaces that come after the period and the first letter of the name of the film?

I think I'd go for reading in a whole line at a time and then pass that line into the constructor of a CFilm class:

std::vector< CFilm > vFilms;

while( ! infile.fail() ){
   std::string strLineFromFile;
   std::getline( infile, strLineFromFile );
   
   /* add this film to the vector of films */
   vFilms.push_back( CFilm( strLineFromFile ) );
}

Then you just need to make a Split function that you can call in the constructor to break the line down into the component parts:

class CFilm
{
public:
   enum EnumGenre{
      eUnknown        = -1,
      eAction         =  0,
      eThriller       =  1,
      eMyOtherGenre   =  2,
   };

   CFilm();

   /* This is the constructor that does all the work */
   CFilm( const std::string& strInput ){
      std::vector< std::string > vFilmElements = Split( strInput, ';' );
      
      if ( vFilmElements.length() == 8 ){
         /* Assign value to the members */
         M_strName = vFilmElements[0];
         
         /* Need to split up the genres */
         std::vector< std::string > vGenreElements = Split( vFilmElements[1], '/' );
         
         /* Need to make a function to convert a genre string to an enum */
         for ( size_t i = 0; i < vGenreElements.size(); ++i )
            M_vGenres.push_back( StringToGenre( vGenreElements[i] ) );

         /* and so on... */
      }
   }
   
private:
   std::string M_strTitle;
   std::vector< EnumGenre > M_vGenres;
   std::string M_strCountry;
   int M_iYear;
   double M_dDuration;
   CName M_director;
   std::string M_strMusic;
   std::vector< CName > M_vCast; 
};

I've illustrated a film class that includes an enum for the genre and a new CName class, but this isn't strictly necessary. The only remaining thing is to write the Split function. I'm not going to write the code for that, but you should look up the find member function of std::string (I like cplusplus.com). You can use find to look for the character that you want to split the string on. I'd also recommend passing a second argument to the Split function that defines what character to split on, that way you can re-use the function more easily.

Hope that helps a little :)

2 Fbody: I'm sorry. The first name field was name of movie in my native language. I deleted this field but I forget change the source code.

2 Lerner: I'm not quite sure what you mean by your post. Is there any error in code? Or I can't use as leading characters numbers?

2 ravenous: Thanks for your examples I'll look to them. But I'm sure that I will have another questions :)

Ok guys. I need one more advice. :D

When a user enter genre of movie, i need to search in

myData[i].genre

and find every movie that has genre like entered value and output would be the names of film with wanted genre.

Is that even possible to do simething like that?

well if you want to search for movies with a particular genre you could use a for loop. Assuming myData is a vector and genre is a string you could use this.

string searchGenre;
cout << "Please enter the genre to search: ";
cin >> searchGenre
vector<t_film> matches;
// find matches and store
for (size_t i = 0; i < myData.size(); i++)
{
    if (myData[i].genre == searchGenre)
        matches.push_back(myData[i]);
}
// display matches
for (size_t i = 0; i < matches.size(); i++)
{
    cout << matches[i].name;
}

You don't have to store the matches if you just want to display them but it could make it easier if you want to break it up into smaller chunks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.