Nested Loops and input from file

Hey guys, I'm really, really new to C++ programming and I'm kind of stuck on my project due in a couple days. We're supposed to read data from a txt document that looks like this:

The rainfall for Gotham City for years 1995 through 2004
total years
10
year jan feb mar apr may jun jul aug sep oct nov dec
1995 5.4 2.4 3.6 7.8 3.3 2.9 2.2 2.3 3.4 4.3 4.5 4.0
1996 3.7 2.9 3.8 9.3 2.6 4.1 3.2 2.8 3.2 3.8 2.7 3.3
1997 4.5 3.2 3.2 5.3 4.1 3.6 3.6 2.1 3.7 4.1 2.0 2.8
1998 2.7 2.8 3.0 7.2 3.8 1.8 1.9 1.7 2.2 3.1 2.7 2.5
1999 3.0 2.1 3.3 5.5 2.7 2.1 2.5 2.7 2.8 3.5 3.8 4.3
2000 2.9 2.4 3.7 4.2 3.5 1.6 2.8 2.5 3.5 3.4 2.3 2.5
2001 4.9 3.5 2.9 3.8 2.1 2.3 1.5 1.5 2.1 2.8 2.5 2.1
2002 1.5 1.7 1.8 2.2 1.0 1.6 1.8 1.6 1.9 2.5 3.2 3.7
2003 2.1 2.8 2.9 4.8 5.5 6.7 5.3 4.7 4.3 3.9 4.1 3.9
2004 3.1 3.2 2.8 5.8 2.0 2.8 3.1 2.4 2.9 3.3 4.9 4.2

We're supposed to use nested loops to determine the year, month and rainfall of that month, but I don't even really know where to begin. This is where I'm at so far.
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
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
	ifstream inputfile;
	int nmbryears;
	double year;

	
	inputfile.open ("rainfall.txt");
	if (!inputfile)
		cout<<"There was an error opening the file."<<endl;
	else
	{
		inputfile.ignore(71); 
		inputfile>>nmbryears;
		inputfile.ignore(75);
		inputfile>>year;
		for (;year<=1995;year++)
		{
			for (
		

	}

	
	
	
	
	
	
	
	
	
	
	
	return 0;
}


I know that the outer loop will control which year is being read and the inner loop will enter the data for each month in that year, but I'm unsure how to do that. I'm not asking for someone to do this for me, I'm just asking for some hints and tips, because I'm pretty lost :P. Thanks.

What is the output of your program supposed to be?

The >> operator needs space on both sides: inputfile >> year;

I would avoid using ignore, instead find a method that reads an entire line.

Unless you are supposed to use a more sophisticate data structure (e.g. map), I would store the data in a 2D array. You could put all of the data in the array directly or leave out the years and just keep the first one (since they are sequential...otherwise you'll have to store them as well).

The iterator for your loops should not be a data member!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
double data[20][12]; //note that 20 is arbitrary and "large enough", 12 is months in a year
double unneeded;
int firstyear, nmbryears;

readline!!!
inputfile >> nmbryears;
readline!!!
inputfile >> firstyear;

for(int i=0; i<nmbryears; i++){
  for(int j=0; j<12; j++){
    inputfile >> data[i][j];//grab data
  }
  inputfile >> unneeded;//dont grab year numbers
}

cout << "Rainfall in 5/98 was " << data[5-1][1998-firstyear];
Thanks for your help turbozedd. Ok, well the output of my program should be something similiar to this:

There were 3 years of data
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Total
-----------------------------------------------------------------------
1995 5.4 2.4 3.6 7.8 3.3 2.9 2.2 2.3 3.4 4.3 4.5 4.0 46.1
1996 3.7 2.9 3.8 9.3 2.6 4.1 3.2 2.8 3.2 3.8 2.7 3.3 45.4
1997 4.5 3.2 3.2 5.3 4.1 3.6 3.6 2.1 3.7 4.1 2.0 2.8 42.2
-----------------------------------------------------------------------
The monthly average over 3 years was 3.7

I am forced to use the ignore function for this project. I don't understand how I will store the data retrieved from the file to be identical to the table above. Im thinking I have to use the setw function. For all of the rainfall amounts im thinking that I should use setw(4)
So I guess where I'm stuck is how I can store the data and output it like the table above. Thanks for your help!
Edit: I'm going to be outputting only to a file, so I'll need to include
1
2
ofstream outputfile;
outputfile.open ("output.txt")

I'm thinking that I'm going to need to use loops to output the data to my output file as soon as it is read from the input file. But, I don't understand how to do that... I'm confused :p
Last edited on
Just put the output in another double loop.
It is almost the same as input.
1
2
3
4
5
6
7
8
9
10
11
12
13
//output heading here
for(int i=0; i<nmbryears; i++){
  for(int j=0; j<12; j++){
    //more output here
    outpufile << data[i][j] << " ";
    //something like yearsum+=data
  }
  //output yearsum
  //output endline
  //completesum+=yearsum
}
//output average
Turbozedd, you are helping me out so much! I really appreciate it! Before I include any other output, I just wanted to make sure my table is set up correctly. Using this code:
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
#include<iostream>
#include<fstream>
#include <iomanip>
using namespace std;

int main()
{
	ifstream inputfile;
	ofstream outputfile;
	int nmbryears;
	double data[20][12];
	int firstyear;
	int i;
	int j;
	
	

	
	

	
	inputfile.open ("rainfall.txt");
	if (!inputfile)
		cout<<"There was an error opening the file."<<endl;
	else
	{
		outputfile.open ("output.txt");
		inputfile.ignore(71); 
		inputfile >> nmbryears;
		inputfile.ignore(75);
		inputfile >> firstyear;
		outputfile <<"There were "<<nmbryears<<" years of data."<<endl;
		for(i=0; i<nmbryears; i++)
		{
			for(j=0; j<12; j++)
			{
    
				inputfile >> data[i][j];
				
				 outputfile << data[i][j] << " ";

  }
			
		}
	
	}

	
	
	return 0;
}

My output is:

5.4 2.4 3.6 7.8 3.3 2.9 2.2 2.3 3.4 4.3 4.5 4 1996 3.7 2.9 3.8 9.3 2.6 4.1 3.2 2.8 3.2 3.8 2.7 3.3 1997 4.5 3.2 3.2 5.3 4.1 3.6 3.6 2.1 3.7 4.1 2 2.8 1998 2.7 2.8 3 7.2 3.8 1.8 1.9 1.7 2.2 3.1 2.7 2.5 1999 3 2.1 3.3 5.5 2.7 2.1 2.5 2.7 2.8 3.5 3.8 4.3 2000 2.9 2.4 3.7 4.2 3.5 1.6 2.8 2.5 3.5 3.4 2.3 2.5 2001 4.9 3.5 2.9 3.8 2.1 2.3 1.5 1.5 2.1 2.8 2.5 2.1 2002 1.5 1.7 1.8 2.2 1 1.6 1.8 1.6 1.9 2.5 3.2 3.7 2003 2.1 2.8 2.9 4.8 5.5 6.7 5.3 4.7 4.3 3.9 4.1 3.9 2004 3.1 3.2 2.8

I notice two problems with this. 1) my columns are not lined up and 2) the year 1995 is missing.
Also, is it possible to use <<showpoint<<setprecision(2) on the output of each piece of data?


Try setting the ios flags
i.e.

cout << setprecision(1) << setiosflags ( ios_base::fixed);
I didn't learn how to set ios flags in class yet, and we can't use anything that wasn't covered in class. But thanks for your suggestion! :)
you need cout << endl after the INNER loop.
you need cout << firstyear before BOTH loops.

take a look at the code i wrote before. this is in there as comments...well most of it lol... i absorbed firstyear into the heading :P

cout.setprecision(2); will work but youll have to switch to 3 for the average, then back again.

Last edited on
code tidying... try to make it nice for us to read :) your instructor too == happy grading
(i dont know what editor you are using but 4 spaces should be set as a tab, somepeople even like 2 spaces)

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
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

int main()
{
    ifstream inputfile;
    ofstream outputfile;
    int nmbryears;
    double data[20][12];
    int firstyear;
    int i;
    int j;

    inputfile.open ("rainfall.txt");
    if (!inputfile)
        cout<<"There was an error opening the file."<<endl;
    else
    {
        outputfile.open ("output.txt");
        inputfile.ignore(71); 
        inputfile >> nmbryears;
        inputfile.ignore(75);
        inputfile >> firstyear;
        outputfile <<"There were "<<nmbryears<<" years of data."<<endl;
        for(i=0; i<nmbryears; i++)
        {
            for(j=0; j<12; j++)
            {
                inputfile >> data[i][j];
                outputfile << data[i][j] << " ";
            }
        }
    }

    return 0;
}
Last edited on
Thanks a bunch guys. My professor said this is the hardest project we're going to do all year, so I really do appreciate your help! I'm still having some trouble though :P This is my code:
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
#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

int main()
{
    ifstream inputfile;
    ofstream outputfile;
    int nmbryears;
    double data[20][12];
    int firstyear;
    int i;
    int j;

    inputfile.open ("rainfall.txt");
    if (!inputfile)
        cout<<"There was an error opening the file."<<endl;
    else
    {
        outputfile.open ("output.txt");
        inputfile.ignore(71); 
        inputfile >> nmbryears;
        inputfile.ignore(75);
        inputfile >> firstyear;
        outputfile << "There were "<<nmbryears<<" years of data."<<endl;
        outputfile << "Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Total"<<endl;
		outputfile << "-----------------------------------------------------------------------"<<endl;
		outputfile << firstyear;
		outputfile <<" ";
		for(i=0; i<nmbryears; i++)
        {
            
			for(j=0; j<12; j++)
			{
                
				inputfile >> data[i][j];
                outputfile << showpoint << setprecision(2);
				outputfile << data[i][j] << " ";
				
            }
        }
    }

    return 0;
}


My output is:

There were 10 years of data.
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Total
-----------------------------------------------------------------------
1995 5.4 2.4 3.6 7.8 3.3 2.9 2.2 2.3 3.4 4.3 4.5 4.0 2.0e+003 3.7 2.9 3.8 9.3 2.6 4.1 3.2 2.8 3.2 3.8 2.7 3.3 2.0e+003 4.5 3.2 3.2 5.3 4.1 3.6 3.6 2.1 3.7 4.1 2.0 2.8 2.0e+003 2.7 2.8 3.0 7.2 3.8 1.8 1.9 1.7 2.2 3.1 2.7 2.5 2.0e+003 3.0 2.1 3.3 5.5 2.7 2.1 2.5 2.7 2.8 3.5 3.8 4.3 2.0e+003 2.9 2.4 3.7 4.2 3.5 1.6 2.8 2.5 3.5 3.4 2.3 2.5 2.0e+003 4.9 3.5 2.9 3.8 2.1 2.3 1.5 1.5 2.1 2.8 2.5 2.1 2.0e+003 1.5 1.7 1.8 2.2 1.0 1.6 1.8 1.6 1.9 2.5 3.2 3.7 2.0e+003 2.1 2.8 2.9 4.8 5.5 6.7 5.3 4.7 4.3 3.9 4.1 3.9 2.0e+003 3.1 3.2 2.8

And I have a whole buch of questions... haha.
Theres something really wrong here. For 2004, all of the data isn't showing up, and I'm perplexed why. Also, how do I use different setprecision on the years and data for the months? Lastly, how do I format the output to look like this table?
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Total
-----------------------------------------------------------------------
1995 5.4 2.4 3.6 7.8 3.3 2.9 2.2 2.3 3.4 4.3 4.5 4.0 46.1
1996 3.7 2.9 3.8 9.3 2.6 4.1 3.2 2.8 3.2 3.8 2.7 3.3 45.4
1997 4.5 3.2 3.2 5.3 4.1 3.6 3.6 2.1 3.7 4.1 2.0 2.8 42.2
-----------------------------------------------------------------------

you need to put cout << endl; after the first loop... read my previous message

also after the first loop you need output firstyear+i

I would recommend using separate loops for the input and output. especially since you should also have a check to make sure that the output file is open-- just like you do for the input file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cout << firstyear << " ";
for(i=0; i<nmbryears; i++)
{
    sum=0
    for(j=0; j<12; j++)
    {
        cout << showpoint << setprecision(2);
        cout << data[i][j] << " ";
        sum+=data[i][j];
    }
    cout << showpoint << setprecision(3);
    cout << sum/12;
    cout << endl;
    cout << firstyear+i << " ";
}
Last edited on
I keep saying average... ignore the division by 12.
Turbozedd, I am sooo close I can taste it! Ok, first off, I have to have the input in the same loop as the output or I will be docked points. Here is my code as of now:
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
 #include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

int main()
{
    ifstream inputfile;
    ofstream outputfile;
    int nmbryears;
    double data[20][12];
    int firstyear;
    int i;
    int j;
	double sum;
	double average;

    inputfile.open ("rainfall.txt");
    if (!inputfile)
        cout<<"There was an error opening the file."<<endl;
    else
    {
		outputfile.open ("output.txt");
        inputfile.ignore(71); 
        inputfile >> nmbryears;
        inputfile.ignore(75);
        inputfile >> firstyear;
        outputfile << "There were "<<nmbryears<<" years of data."<<endl;
        outputfile << "Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Total"<<endl;
		outputfile << "----------------------------------------------------------"<<endl;
		outputfile << firstyear << " ";
		for(i=1; i<=nmbryears; i++)
        {
            sum=0;
			for(j=0; j<12; j++)
			{
                
				inputfile >> data[i][j];
                outputfile << showpoint << setprecision(2);
				outputfile << data[i][j] << " ";
				sum+=data[i][j];
				
            }
				outputfile << showpoint << setprecision(3);
				outputfile << sum;
				outputfile << endl;
				outputfile << firstyear+i << " ";
				
				
		}
		outputfile << endl;
    }
	average=(sum/(nmbryears*12));
	outputfile << "----------------------------------------------------------"<<endl;
	outputfile <<"The monthly average over "<<nmbryears<<" years was "<<average<<endl;
	inputfile.close();
	outputfile.close();


    return 0;
}


And heres my output:

There were 10 years of data.
Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Total
----------------------------------------------------------
1995 5.4 2.4 3.6 7.8 3.3 2.9 2.2 2.3 3.4 4.3 4.5 4.0 46.1
1996 2.0e+003 3.7 2.9 3.8 9.3 2.6 4.1 3.2 2.8 3.2 3.8 2.7 2.04e+003
1997 3.3 2.0e+003 4.5 3.2 3.2 5.3 4.1 3.6 3.6 2.1 3.7 4.1 2.04e+003
1998 2.0 2.8 2.0e+003 2.7 2.8 3.0 7.2 3.8 1.8 1.9 1.7 2.2 2.03e+003
1999 3.1 2.7 2.5 2.0e+003 3.0 2.1 3.3 5.5 2.7 2.1 2.5 2.7 2.03e+003
2000 2.8 3.5 3.8 4.3 2.0e+003 2.9 2.4 3.7 4.2 3.5 1.6 2.8 2.04e+003
2001 2.5 3.5 3.4 2.3 2.5 2.0e+003 4.9 3.5 2.9 3.8 2.1 2.3 2.03e+003
2002 1.5 1.5 2.1 2.8 2.5 2.1 2.0e+003 1.5 1.7 1.8 2.2 1.0 2.02e+003
2003 1.6 1.8 1.6 1.9 2.5 3.2 3.7 2.0e+003 2.1 2.8 2.9 4.8 2.03e+003
2004 5.5 6.7 5.3 4.7 4.3 3.9 4.1 3.9 2.0e+003 3.1 3.2 2.8 2.05e+003
2005
----------------------------------------------------------
The monthly average over 10 years was 17.1

Ok, so I made some minor changes to my previous code, using your help, and a little bit of my intelligence for once :). I set i=1 and changed the condition of the outer loop to i<=nmbryears. So far so good. Unfortunately, in my output I'm getting very weird numbers that are shifting every other number to the right. ex: 2.0e+003. I tried fooling around with the code, but I couldn't manage to get rid of those numbers. Also, the year 2005 is lingering on the bottom, and once again, I have no idea why... Lastly :P, I know my code for calculating the sum average=(sum/(nmbryears*12)); is wrong. Thank you soo much for your help!
Edit: Oh, and my braces are lined up in my actual code, but when I post it here they get messed up, sorry!
Last edited on
nevermind, I figured it out! Thanks for everything guys!!!!
Topic archived. No new replies allowed.