using fstream across main.cpp/functions.cpp/functions.h

Apr 5, 2020 at 10:42pm
*Edit: formatting

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
----------
1
2
3
4
5
6
7
8
9
10
11
#ifndef PROGRAMMING_FUNCTIONS_H
#define PROGRAMMING_FUNCTIONS_H

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

void readMovie(ifstream infile, string movieInput);

#endif 


--------
functions.cpp
--------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include "functions.h"
#include <fstream>
using namespace std;

string movie = "";

ifstream infile("in.txt");

void readMovie(ifstream infile, string movieInput)
{
    while (getline(infile, movie))
    {
        infile>>movieInput;
        infile.ignore();
    }

}

------
main.cpp
------
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
#include <iostream>
#include <string>
#include "functions.h"
#include <fstream>



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",????);

            break;
(switch continues with all cases)


Last edited on Apr 6, 2020 at 3:04am
Apr 6, 2020 at 2:14am
Hello nixUe,


PLEASE ALWAYS USE CODE TAGS (the <> formatting button), to the right of this box, when posting code.

Along with the proper indenting it makes it easier to read your code and also easier to respond to your post.

http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/

Hint: You can edit your post, highlight your code and press the <> formatting button, but you may still to indent your code.

You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.


This is untested because I did not finish "main" and do not have the input file you are using to test it with.

Please post the input file or a good sample if to large.

This is untested, but I think it should work:
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
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
1
2
3
std::stringinFileName{ "in.txt" };

ifstream inFile(inFileName);


Andy

Edit: Added code.
Last edited on Apr 6, 2020 at 2:16am
Apr 6, 2020 at 3:00am
Thank you for the note about formatting (new to this website as well)

I appreciate the detail of your answer, you're a life saver!

For the sake of making things easier for myself, ive included everything in one main.cpp

Im not too familiar with vectors, but I will be needing arrays to store and sort the movies.

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <iostream>
#include <string>
#include <fstream>


using namespace 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()
{

}





the in.txt consists of
The Wizard of Oz
1939
Deadpool
2016

Edit: added code
Last edited on Apr 6, 2020 at 3:34am
Apr 6, 2020 at 1:25pm
Hello nixUe,

You have taken 3 files that just needed a little rework and tried to put it in 1 file that does not work.

Working with what you started with and some additions I have found this to work:
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*----------
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>

using namespace 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.

	}

	return false;
}

void listMovie()
{
	std::cout << "\n  In list movie\n";
}

void sendMovieToFile()
{

}

void searchMoviesByTitle()
{

}

void sortMovies()
{

}

/*
------
main.cpp
------
*/
#include <iostream>
#include <string>
#include <fstream>

using namespace 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
I believe that you need to stay with that.

Andy
Apr 6, 2020 at 4:54pm
Reading that logic actually made sense in my head!

I do in fact need both the title and the year, is there an easy way to distinguish them as they are different data types?

And yes, for the submission i'd use the 3 files :D

Thank you for all of your help. Gonna be using this community a lot more.

Last edited on Apr 6, 2020 at 4:59pm
Apr 7, 2020 at 9:56am
Hello nixUe,

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.

So another possibility could be:
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
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.

	}

	return false;
}

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.

Andy
Topic archived. No new replies allowed.