I have been recently introduced to C++ and am working on a project that has a menu of actions you can preform in regards to movies. It requires 3 files, main.cpp, functions.cpp, and functions.h
I am struggling with the first action of reading in the movies.
One of the concepts i'm struggling with is the ifstream. I understand how it works. But trying to implement it with different files is a little confusing.
I have a function that is for reading in from a text file, and where im stuck is calling the function.
I understand the function would need two parameters for the getline to read in the data. Those two parameters being the actual txt file, and then a string that is being read? (Not sure if that part is correct either)
What I don't understand is how I would call the function back in my main.cpp if all the stuff for ifstream is in another file. I know the first part of it would be readMovies("in.txt", ) but i'm confused on what the second parameter is.
----------
functions.h
----------
#include <iostream>
#include <string>
#include "functions.h"
#include <fstream>
usingnamespace std;
int main() {
int menuChoice;
string movieFromFile;
cout<<"Welcome to the Movie app!, your menu consists of\n1. Read in Movies from file\n2. List Movies to the Screen\n3. List Movies to a File \n4. Search Movies by Title\n5. Sort Movies by Title\n6. Exit\n";
cin>>menuChoice;
switch (menuChoice)
{
case 1:
cout<<"Reading movies from file"<<endl;
readMovie("in.txt",????);
break;
(switch continues with all cases)
functions.h
----------
#ifndef PROGRAMMING_FUNCTIONS_H
#define PROGRAMMING_FUNCTIONS_H
//#include <iostream> // <--- You should not have to put these in a header file.
//#include <string>
//#include <fstream>
//using namespace std; // <--- Should never be put in a header file.
// http://www.lonecpluspluscoder.com/2012/09/22/i-dont-want-to-see-another-using-namespace-xxx-in-a-header-file-ever-again/
void readMovie(ifstream infile, string movieInput);
#endif
--------
functions.cpp
--------
#include <iostream>
#include <fstream>
#include <string>
#include "functions.h"
using namespace std;
string movie; // <--- Does not need initialized as it is empty when defined until you put somethinfg in it.
void readMovie(ifstream infile, string movieFromFile)
{
ifstream infile("in.txt");
while (getline(infile, movieFromFile))
{
// <--- Need to store what is read into something. A vector or an array.
// <--- Otherwise youare just overwriting the variable with new information.
//infile >> movieInput;
//infile.ignore();
}
}
------
main.cpp
------
#include <iostream>
#include <string>
#include <fstream>
#include "functions.h"
using namespace std;
int main()
{
int menuChoice;
string movieFromFile;
cout << "Welcome to the Movie app!, your menu consists of\n1. Read in Movies from file\n2. List Movies to the Screen\n3. List Movies to a File \n4. Search Movies by Title\n5. Sort Movies by Title\n6. Exit\n";
cin >> menuChoice;
switch (menuChoice)
{
case 1:
cout << "Reading movies from file" << endl;
readMovie("in.txt", movieFromFile);
break;
(switch continues with all cases)
Notice that I changes the order of the include files in the ".cpp" files. This should make a difference.
I do not know what is in the input file or what you need to keep track of. I do not know if you know about "vectors" yet or if you would need an array to store what you read, but you need something.
Those two parameters being the actual txt file, and then a string that is being read? (Not sure if that part is correct either)
Partially correct. The two parameters of "std::getline" are the stream and the string to read into.
If you are referring to the "ifstream" the only parameter is the file name. This can be a constant in double quotes, e.g., ifstream inFile("in.txt"); or
#include <iostream>
#include <string>
#include <fstream>
usingnamespace std;
void readMovie(ifstream &infile);
void listMove();
void sendMovieToFile();
void searchMoviesByTitle();
void sortMovies();
string movieInput = "";
char ch_arr[3][10];
int main() {
int menuChoice;
ifstream infile("in.txt");
infile.open("in.txt");
cout<<"Welcome to the Movie app!, your menu consists of\n1. Read in Movies from file\n2. List Movies to the Screen\n3. List Movies to a File \n4. Search Movies by Title\n5. Sort Movies by Title\n6. Exit\n";
cin>>menuChoice;
switch (menuChoice)
{
case 1:
cout<<"Reading movies from file"<<endl;
readMovie((ifstream &) "in.txt");
break;
case 2:
cout<<"Listing movies!"<<endl;
listMove();
break;
case 3:
cout<<"Sending movies to the output file"<<endl;
sendMovieToFile();
break;
case 4:
cout<<"Which movie would you like to search for?"<<endl;
searchMoviesByTitle();
break;
case 5:
cout<<"Sorting movies alphabetically"<<endl;
sortMovies();
break;
case 6:
cout <<"Goodbye!"<<endl;
return 0;
default:
cout<<"Invalid input"<<endl;
break;
}
return 0;
}
void readMovie(ifstream &infile)
{
while (getline(infile, movieInput))
{
// infile>>movieInput;
// infile.ignore();
}
}
void listMove()
{
}
void sendMovieToFile()
{
}
void searchMoviesByTitle()
{
}
void sortMovies()
{
}
/*----------
functions.h
----------
*/
#ifndef PROGRAMMING_FUNCTIONS_H
#define PROGRAMMING_FUNCTIONS_H
bool readMovie(string& movieFromFile);
void listMovie();
void sendMovieToFile();
void searchMoviesByTitle();
void sortMovies();
#endif
/*
--------
functions.cpp
--------
*/
#include <iostream>
#include <fstream>
#include <string>
usingnamespace std;
#include "functions.h"
//string movie; // <--- Does not need initialized as it is empty when defined until you put somethinfg in it.
// Also it should not be a global variable and it is not needed. Maybe later.
bool readMovie(string& movieFromFile)
{
ifstream infile("in.txt");
if (!infile)
{
std::cout << "\n Error message\n";
return 1;
}
while (getline(infile, movieFromFile))
{
// <--- Need to store what is read into something. A vector or an array.
// <--- Otherwise you are just overwriting the variable with new information.
std::cout << movieFromFile << std::endl; // <--- Used as a break point for testing.
getline(infile, movieFromFile);
std::cout << movieFromFile << std::endl; // <--- Used as a break point for testing.
}
returnfalse;
}
void listMovie()
{
std::cout << "\n In list movie\n";
}
void sendMovieToFile()
{
}
void searchMoviesByTitle()
{
}
void sortMovies()
{
}
/*
------
main.cpp
------
*/
#include <iostream>
#include <string>
#include <fstream>
usingnamespace std;
#include "functions.h"
int main()
{
int menuChoice;
string movieFromFile;
ifstream infile("in.txt");
cout << "Welcome to the Movie app!, your menu consists of\n1. Read in Movies from file\n2. List Movies to the Screen\n3. List Movies to a File \n4. Search Movies by Title\n5. Sort Movies by Title\n6. Exit\n";
cin >> menuChoice;
switch (menuChoice)
{
case 1:
cout << "Reading movies from file" << endl;
if (readMovie(movieFromFile))
return 1;
break;
case 2:
cout << "Listing movies!" << endl;
listMovie();
break;
case 3:
cout << "Sending movies to the output file" << endl;
sendMovieToFile();
break;
case 4:
cout << "Which movie would you like to search for?" << endl;
searchMoviesByTitle();
break;
case 5:
cout << "Sorting movies alphabetically" << endl;
sortMovies();
break;
case 6:
cout << "Goodbye!" << endl;
return 0;
default:
cout << "Invalid input" << endl;
break;
}
return 0;
}
Since the only place you actually need the file stream is in the read function I moved it there. This way you open the file stream there and it closed when the function ends. It makes it easier than passing the stream form "main" to the function. If you need or prefer to open the stream in "main" and pass it to the function that is easily fixed. Your choice.
I reworked case 1 and the function to better deal with the file not opening.
Lines 51 and 55 are used for testing and should be removed later.
The one thing missing from the read while loop is storing what is read from the file into something. The question is do you want to store the title and date or just the title. It does make a difference.
It is hard to guess at what you need to do. but the instructions say:
It requires 3 files, main.cpp, functions.cpp, and functions.h
How you read the year and what type of variable you use will depend on what you need to do with it.
In the code I posted, for now, I just read the year into a string using "getline" because it was easier and at the time I did not see any reason for anything different.
bool readMovie(string& movieFromFile)
{
int year{};
ifstream infile("in.txt");
if (!infile)
{
std::cout << "\n Error message\n";
return 1;
}
while (getline(infile, movieFromFile))
{
// <--- Need to store what is read into something. A vector or an array.
// <--- Otherwise you are just overwriting the variable with new information.
std::cout << movieFromFile << std::endl; // <--- Used as a break point for testing.
infile >> year;
infile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>.
std::cout << movieFromFile << std::endl; // <--- Used as a break point for testing.
}
returnfalse;
}
I did not change everything just the important part in bold.
As the comment says you need to store the information read in something so you only have to read the file once.
The problem is I do not know what you have learned. I would suggest using a struct to store the information and put that in a vector, but an array would work if you have not learned about vectors yet. And that is one possibility.
The program works with 3 files, but it is not complete. Just a plact to start frrom.