Adding/averaging numbers from a text file

I am really new to programming and this is probably something really simple but I have not found any videos or info on how to do it. I am trying to get specific positions from a file and add/average the numbers.

This is the text file(I will use [n] as line position, not as part of the file):

1
2
3
4
5
2016 116 303.1 Passengers 
2014 169 677.5 Interstellar 
2015 141 630.2 The Martian 
2013 91 723.2 Gravity 
2016 116 203.4 Arrival


For example, how would I get just 116 or 169, to add them together? I have to use their positions because the numbers themselves will be different but the format of the txt file will be the same.

Last edited on
It does look line that each line contains
int int double text


I would read each line into a string with getline.
Then, I would create istringstream from that string,
read int, int, double with formatted input and text with getline
from that istringstream object.
http://www.cplusplus.com/reference/sstream/istringstream/
If the format of each line is {int} {int} {double} {string with one or more words}, parsing it isn't too bad.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main()
{
	ifstream fin("movies.txt");
	
	int year;
	int number; // choose a better name, I'm just guessing as to what it means
	double rating; // choose a better name, I'm just guessing as to what it means
	while (fin >> year >> number >> rating)
	{
		string name;
		if (getline(fin >> ws, name))
		{
			cout << "Movie Year:   " << year << '\n'
			     << "Movie number: " << number << '\n'
			     << "Movie rating: " << rating << '\n'
			     << "Movie name:   " << name << "\n\n";
		}
	}
}

Input (movies.txt):
2016 116 303.1 Passengers
2014 169 677.5 Interstellar
2015 141 630.2 The Martian
2013 91 723.2 Gravity
2016 116 203.4 Arrival


Output:
Movie Year:   2016
Movie number: 116
Movie rating: 303.1
Movie name:   Passengers

Movie Year:   2014
Movie number: 169
Movie rating: 677.5
Movie name:   Interstellar

Movie Year:   2015
Movie number: 141
Movie rating: 630.2
Movie name:   The Martian

Movie Year:   2013
Movie number: 91
Movie rating: 723.2
Movie name:   Gravity

Movie Year:   2016
Movie number: 116
Movie rating: 203.4
Movie name:   Arrival


Note, the "fin >> ws" line filters out any whitespace before the getline call itself.
>> is delimited by whitespace, but getline can retain whitespace (in case the movie title is multiple words).

A file needs to be parsed. There's no way of magically jumping to the line that contains the number 169. You need to figure it out and check. A file is just characters/bytes.

Since the parsing here is relatively simple, I don't think you need to use stringstreams.

If you want to average them, then keep a variable for total number, and another variable for the number of movies, and then at the end, divide the total number by the number of movies.
Last edited on
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
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;

//==========================================================

struct Movie
{
   int year;
   int minutes;
   double data;
   string name;
};

istream &operator >> ( istream &in, Movie &movie )
{
   in >> movie.year >> movie.minutes >> movie.data;
   getline( in >> ws, movie.name );
   return in;
}

//==========================================================

int main()
{
// ifstream in( "movies.txt" );
   istringstream in( "2016 116 303.1 Passengers\n"
                     "2014 169 677.5 Interstellar\n"
                     "2015 141 630.2 The Martian\n"
                     "2013 91 723.2 Gravity\n"
                     "2016 116 203.4 Arrival\n"     );

   vector<Movie> films;
   for ( Movie movie; in >> movie; films.push_back( movie ) );

   int sum = 0;
   for ( Movie &movie : films ) sum += movie.minutes;
   cout << "Sum = " << sum << '\n';
   cout << "Average = " << (double)sum / films.size() << '\n';
}


Sum = 633
Average = 126.6




If you aren't interested in storing all movie data, then you can find sums and averages of one column with much less:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int main()
{
// ifstream in( "movies.txt" );
   istringstream in( "2016 116 303.1 Passengers\n"
                     "2014 169 677.5 Interstellar\n"
                     "2015 141 630.2 The Martian\n"
                     "2013 91 723.2 Gravity\n"
                     "2016 116 203.4 Arrival\n"     );
                     
   string dummy;
   int sum = 0, num = 0;
   for ( int value; in >> dummy >> value && getline( in, dummy ); num++ ) sum += value;
   cout << "Sum = " << sum << '\n';
   cout << "Average = " << (double)sum / num << '\n';
}


Sum = 633
Average = 126.6
Last edited on
Topic archived. No new replies allowed.