read file into an array

Pages: 12
im trying to read a file with 3 columns and each column has a 100 numbers with decimal places.
How have you tried to solve this 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
int exam1[100];// array that can hold 100 numbers for 1st column  
int exam2[100];// array that can hold 100 numbers for 2nd column  
int exam3[100];// array that can hold 100 numbers for 3rd column   
 
void main()  
{  
  ifstream infile;    
 
  int num;  
  infile.open("example.txt");// file containing numbers in 3 columns  
     if(infile.fail()) // checks to see if file opended  
    {  
      cout << "error" << endl;  
    }  
       while(!infile.eof()) // reads file to end of line  
      {  
         for(i=0;i<100;i++); // array numbers less than 100  
           {  
        while(infile >> [exam]); // while reading get 1st array or element  
            ???// how will i go read the next number  
            infile >> num;  
          }  
      }  
  infile.close();  
}  
Why don't you use a 2d-array, like int exam[100][3];? Then use 2 for loops one inside the other like:
1
2
3
for (i=0; i<100; i++)
     for (j=0; j<3; j++) 
          infile>>exam[i][j];
Last edited on
say i want to read another column of numbers like the ones before into another array. will i use another for loop . will i use like cin.next[]??
Hey, m4ster r0shi, he's already struggling to keep his head above water with this one... please don't push him under with new stuff.

timbomo
You can get rid of lines 15, 16, and 23, since they are not useful the way you have it. (Also, you shouldn't test against the End Of File condition in C++ file handling loops, but don't worry about that for now.)

Line 19 rehashes the problem with line 15; You don't need it either.


On line 21, you are trying to input a number into each exam. It so happens that the loop you have on line 17 uses a variable (named i) which is also the index of the score in each of the three exams (0 through 99). So, try reading each exam's score, one at a time, in the loop:
17
18
19
20
21
22
  for (i=0; i<100; i++) //; Don't put a semi-colon here. See the URL below.
    {
      infile >> exam1[i];
      infile >> exam2[i];
      infile >> exam3[i];
    }

This code doesn't handle errors (such as a file with less than 100 scores for each of the three exams) very well, but it now does what you want. If you like, you can write it more succinctly as:
17
18
19
20
  for (i=0; i<100; i++)
    {
      infile >> exam1[i] >> exam2[i] >> exam3[i];
    }


Here is the URL I promised above:
http://www.cplusplus.com/doc/tutorial/control/#loops

Remember that in C and C++ the semi-colon terminates statements. So a line like
while (a < b) ;
is the same as
while (a < b) { }

They read as:
while (a < b) /*empty statement*/;
and
while (a < b) {/*empty statements*/}


A couple of final notes, if you will. Line 5 should read int main() and your program should end with
24
25
26
  infile.close();
  return 0;
}

Indentation makes a big difference. Be careful with it! You'll understand your programs much better!

Hope this helps.
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
// basic file operations
#include <iostream>
#include <fstream>
using namespace std;
int read_file_in_array(int exam[100][3]);
int calculate_total(int exam1[], int exam2[], int exam3[]); // function that calcualates grades to see how many 90,80,70,60
void display_totals();
int exam1[100][3];// array that can hold 100 numbers for 1st column
int exam2[100][3];// array that can hold 100 numbers for 2nd column
int exam3[100][3];// array that can hold 100 numbers for 3rd column 
int main()
{
	int go,go2,go3;
	go=read_file_in_array;
	go2= calculate_total(exam1[],exam2[],exam3[]);
	go3=display_totals;
	cout << go,go2,go3;
	return 0;
}
void display_totals()
{

	int grade_total;
	grade_total=calculate_total(exam1[],exam2[],exam3[]);
}	
int calculate_total(int exam1[],int exam2[],int exam3[])
{
	int calc_tot,above90=0, above80=0, above70=0, above60=0,i,j;
	calc_tot=read_file_in_array(exam[100][3]);
	exam1[][]=exam[100][3];
	exam2[][]=exam[100][3];
	exam3[][]=exam[100][3];
	for(i=0;i<100;i++);
		{
			if(exam1[i] <=90 && exam1[i] >=100)
				{
					above90++;
					cout << above90;
				}
		}
		return exam1[i],exam2[i],exam3[i];
					
}

int read_file_in_array(int exam[100][3])
{
  ifstream infile;  

  int num, i=0,j=0;
  infile.open("grades.txt");// file containing numbers in 3 columns
	if(infile.fail()) // checks to see if file opended
	{
		cout << "error" << endl;
	}
  while(!infile.eof()) // reads file to end of line
	  {
		  for(i=0;i<100;i++); // array numbers less than 100
		  {
			for(j=0;j<3;j++); // while reading get 1st array or element
			infile >> exam[i][j];
			cout << exam[i][j] << endl;
		  }
	  }
  infile.close();
  return exam[i][j];
}
i get these syntex errors and i dont know why.
its eight of these: error C2059: syntax error : ']'
Hmm... it would be better if you used

either

int exam[100][3];

or
1
2
3
int exam1[100];
int exam2[100];
int exam3[100];

not both.

In the first case, exam[i][j] indicates the number of the (i+1)-th row and (j+1)-th column, where 0<=i<=99 and 0<=j<=2. In the second, well, exam1[i] is the (i+1)-th row of the first column (as you have exam1), exam2[i] is the (i+1)-th row of the second column etc... and 0<=i<=99.

I see here that you input the data from file to exam and then try to place the data from exam to exam1, exam2 and exam3. You could avoid this copying if you only used one way to represent your data.

Another thing is that the copying itself isn't done correctly.
here:
1
2
3
exam1[][]=exam[100][3];
exam2[][]=exam[100][3];
exam3[][]=exam[100][3];

maybe you meant something like:
1
2
3
exam1[][]=exam[100][0];
exam2[][]=exam[100][1];
exam3[][]=exam[100][2];

but neither does what you expect. If you want to copy the data copy each element separately with a loop like this:

1
2
3
4
5
6
for (int i=0; i<100; i++)
{
     exam1[i]=exam[i][0];
     exam2[i]=exam[i][1];
     exam3[i]=exam[i][2];
}

But I would suggest avoid storing data in two places and use only one of the above mentioned ways.

I also noticed the return statements of your functions:
return exam[i][j]; for read_file_in_array
and return exam1[i],exam2[i],exam3[i]; for calculate_total

Both are syntactically correct but the first one doesn't do what you want and the second one is unnecessary (if I understand why you are using it). Let me elaborate on these two...

For the first:
What value do you want calc_tot to hold?? Is it the number of the records in your file? Then perhaps read_file_in_array should return i+1 or i or i*3+j, I don't know, you figure this one out, but exam[i][j] definitely is not what you want. This is the value of the element in the (i+1)-th row and (j+1)=th column...

For the second:
Are you doing this because you want the changes you made to exam1, exam2 and exam3 to be actually stored? This is not necessary. The values are stored. Also exam1[i],exam2[i],exam3[i] evaluates to exam3[i], so you actually return only the last one.

That's all I can see for the time being... Fix these and let me know where you get after that.

EDIT: Also heed Duoas' suggestion and avoid putting ';' in the head of your loops, it is not wrong syntax, but it doesn't do what you want:

You use it like:
1
2
3
4
for (/*...*/) ; //<- this ';' musn't be put here. This here is an empty loop...
{               //this is not
//...           //part of the loop
}               //it will only run once! 

And it should be like:
1
2
3
4
for (/*...*/) //<- do it like this, no ';'. Now, this is the head of your loop...
{              //and this
//...          //is the body
}              //of your loop! 

EDIT 2: I just took a look at your global declarations and your main function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int read_file_in_array(int exam[100][3]);
int calculate_total(int exam1[], int exam2[], int exam3[]); 
// function that calcualates grades to see how many 90,80,70,60
void display_totals();
int exam1[100][3];// array that can hold 100 numbers for 1st column
int exam2[100][3];// array that can hold 100 numbers for 2nd column
int exam3[100][3];// array that can hold 100 numbers for 3rd column 
int main()
{
	int go,go2,go3;
	go=read_file_in_array;
	go2= calculate_total(exam1[],exam2[],exam3[]);
	go3=display_totals;
	cout << go,go2,go3;
	return 0;
}

Functions read_file_in_array and calculate_total return an int each. Function display_totals returns void (i.e. it doesn't return anything). So, when you call display_totals call it like:

display_totals(); //<- don't forget the parentheses!!!

Also, it would be a good idea to make your other functions void, since (if I understand correctly) they don't have to return a value. Then you don't need the variables go, go2 and go3.

Another thing I noticed is that you declare calculate_total to take three arguments and when you call it, the arguments you pass are global variables. You could just not pass them at all! Consider the following examples:

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
#include <iostream>
using namespace std;

int global_int;

void my_function();

int main()
{
     global_int=10;
     my_function();

     global_int=20;
     my_function();

     cout << "hit enter to quit..." << endl;
     cin.get();
}

void my_function()
{
     //see, you don't have to pass global_int as an argument
     //coz it's a global variable. You can simply access it directly
     cout << "your int is: " << global_int << endl;
}

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
#include <iostream>
using namespace std;

void my_function(int some_int);

int main()
{
     int local_int;     

     local_int=1;
     my_function(local_int);

     local_int=2;
     my_function(local_int);

     cout << "hit enter to quit..." << endl;
     cin.get();
}

void my_function(int some_int)
{
     //now, since local_int is declared inside main, you can't
     //access it directly from here... You have to pass it as
     //an argument to your function
     cout << "your int is: " << some_int << endl;
}

If you want more info about multi/single dimensional arrays and/or functions you can have a look at these links:
http://cplusplus.com/doc/tutorial/arrays/
http://cplusplus.com/doc/tutorial/functions/
http://cplusplus.com/doc/tutorial/functions2/

One more (very important) thing:
im trying to read a file with 3 columns and each column has a 100 numbers with decimal places.

Use double instead of int like:

1
2
3
double exam1[100];
double exam2[100];
double exam3[100];

or

double exam[100][3];
Last edited on
how would i declare exams ? its saying a exams are undeclared.
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
// basic file operations
#include <iostream>
#include <fstream>
using namespace std;
void read_file_in_array(int exam[100][3]);
double calculate_total(int exam1[], int exam2[], int exam3[]); // function that calcualates grades to see how many 90,80,70,60
//void display_totals();

int main()
{
	int go,go2,go3;
	go=read_file_in_array(exam);
	go2=calculate_total(exam1,exam2,exam3);
	go3=display_totals();
	cout << go,go2,go3;
	return 0;
}/*
int display_totals()
{

	int grade_total;
	grade_total=calculate_total(exam1,exam2,exam3);
	return 0;
}	*/
double calculate_total(int exam1[],int exam2[],int exam3[])
{
	int calc_tot,above90=0, above80=0, above70=0, above60=0,i,j;
	calc_tot=read_file_in_array(exam);
	for(i=0;i<100;i++)
		{
			exam1[i]=exam[100][0];
			exam2[i]=exam[100][1];
			exam3[i]=exam[100][2];
			if(exam1[i] <=90 && exam1[i] >=100)
				{
					above90++;
					cout << above90;
				}
		}
		return exam3[i];
		
}

void read_file_in_array(double exam[100][3])
{
  ifstream infile;  

  int num, i=0,j=0;
  infile.open("grades.txt");// file containing numbers in 3 columns
	if(infile.fail()) // checks to see if file opended
	{
		cout << "error" << endl;
	}
  while(!infile.eof()) // reads file to end of line
	  {
		  for(i=0;i<100;i++) // array numbers less than 100
		  {
			for(j=0;j<3;j++) // while reading get 1st array or element
			infile >> exam[i][j];
			infile >> exam[i][j];
			infile >> exam[i][j];
			cout << exam[i][j] << endl;
		  }
	  }
  infile.close();
  
}
I gather you didn't bother to read everything I wrote, did you?... :D

Nevermind, let's try again... easier this time...

Before your main function, declare exam like: double exam[100][3];
We declare it as a global variable so that you don't have to pass it as an argument to your functions.

Now, declare your functions to return void and take no arguments, like this:
1
2
void read_file_in_array();
void calculate_total();

And define them like this:
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
void read_file_in_array()
{
    ifstream infile;
    int num, i=0,j=0;

    infile.open("grades.txt");// file containing numbers in 3 columns
    if(!infile) // checks to see if file opended
    {
        cout << "error" << endl;
        return;
    }

    bool stop_reading=false;
    while(true) //loops forever
    {
        for(i=0;i<100;i++) // 100 array rows
        {
            for(j=0;j<3;j++) // 3 array columns
            {
                //stop if error or eof occurs
                if (! (infile >> exam[i][j]) ) {stop_reading=true; break;}
                cout << exam[i][j] << endl;
            }

            if (stop_reading) break;
        }

        if (stop_reading) break;
    }
    
    infile.close();
}

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
void calculate_total()
{
    int above90=0, above80=0, above70=0, above60=0,i,j;

    for(i=0;i<100;i++)
    {
        for (j=0; j<3; j++)
        {
            if(exam1[i][j] >=90)
            {
                above90++;
            }

            if (exam[i][j] >=80)
            {
                above80++;
            }

            //...
            //put your other ifs here...
            //...

	}
    }

    //display results
    cout << "above 60: " << above60 << endl;
    cout << "above 70: " << above70 << endl;
    //do the rest yourself...
}

Now you can call them in main like this:
1
2
3
4
5
6
7
8
9
int main()
{
    read_file_in_array();
    calculate_total();
    
    cout << "hit enter to quit...";
    cin.get();
    return 0;
}
Last edited on
what does the stop reading mean?
stop_reading is a temporary boolean variable (boolean means it can only take two values: true, false). I use it to know when to stop reading data from the file (because I reached the end of file, or some other kind of error occured)

if (stop_reading) is equivalent to if (stop_reading==true)
Last edited on
do i have a different directive like #<include> or do i have to declare the variable stop_reading or is it a pre defined function?
I'm afraid I don't understand your question... :/

EDIT:
(after reading your question twice)
stop_reading is just a helping temporary variable I declare. You don't have to include anything and it's not a predefined function. I declare it and initialize it to false with the line: bool stop_reading=false;
Last edited on
this program does not run correctly and i dont know why?

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
// basic file operations
#include <iostream>
#include <fstream>
using namespace std;
int read_file_in_array(double exam[100][3]);
double calculate_total(double exam1[], double exam2[], double exam3[]); // function that calcualates grades to see how many 90,80,70,60
//void display_totals();
double exam[100][3];
int main()
{
	double go,go2,go3;
	double exam[100][3],exam1[100],exam2[100],exam3[100];
	go=read_file_in_array(exam);
	go2=calculate_total(exam1,exam2,exam3);
	//go3=display_totals();
	cout << go,go2,go3;
	return 0;
}
/*
int display_totals()
{

	int grade_total;
	grade_total=calculate_total(exam1,exam2,exam3);
	return 0;
}	*/
double calculate_total(double exam1[],double exam2[],double exam3[])
{
	int calc_tot,above90=0, above80=0, above70=0, above60=0,i,j, fail=0;
	double exam[100][3];
	calc_tot=read_file_in_array(exam);
	for(i=0;i<100;i++)
		{
		for (j=0; j<3; j++)
			{
			exam1[i]=exam[100][0];
			exam2[i]=exam[100][1];
			exam3[i]=exam[100][2];
			if(exam[i][j] <=90 && exam[i][j] >=100)
				{
				above90++;
					{
					if(exam[i][j] <=80 && exam[i][j] >=89)
						{
						above80++;
							{
							if(exam[i][j] <=70 && exam[i][j] >=79)
								{
								above70++;
									{
									if(exam[i][j] <=60 && exam[i][j] >=69)
										{
										above60++;
											{
											if(exam[i][j] >=59)
												{
												fail++;
											}
											}
									}
									}
							}
							}
					}
					}
			}
		}
	}
	return 0;
}
												
int read_file_in_array(double exam[100][3])
{
	ifstream infile;  
    int exam1[100];
    int exam2[100];
    int exam3[100];
  infile.open("grades.txt");// file containing numbers in 3 columns
	if(infile.fail()) // checks to see if file opended
		{
		cout << "error" << endl;
		}
	int num, i=0,j=0;
	while(!infile.eof()) // reads file to end of line
	  {
		  for(i=0;i<100;i++) // array numbers less than 100
		  {
			for(j=0;j<3;j++) // while reading get 1st array or element
			infile >> exam[i][j];
			infile >> exam[i][j];
			infile >> exam[i][j];
			cout << exam[i][j] << endl;
				{
					if (! (infile >> exam[i][j]) )
					cout << exam[i][j] << endl;
				}
		  exam[i][j]=exam1[i];
		  exam[i][j]=exam2[i];
		  exam[i][j]=exam3[i];
		  }		
	infile.close();
  }
return 0;
}



Your program doesn't work because you don't bother to read the suggestions Duoas and I give you... :/
i guess i dont understand, i get errors saying i cant go from type void to type int
Last edited on
What exactly do you expect from us? To hand you code which does what you want? Maybe I'm wrong but it seems to me that you don't understand because you don't want to understand...

I told you a couple of times to use either double exam[100][3]; or
1
2
3
double exam1[100];
double exam2[100];
double exam3[100];

and not both... But you go and mix these things...

I also told you to make your functions return void and take no arguments (in order to make things easier for you) and I actually showed you how to do this but you insist on declaring them differently...

So, you ignore almost everything I suggest, post some piece of code and complain that it doesn't work... What am I supposed to do? What would you do if you were in my place?
Last edited on
EDIT2 and EDIT3: Just for emphasis, we the eliteveterans of this forum + twicker will NEVER write out the solution to a problem.

Okay. Seriously. What the heck is going on here? Duoas and m4ster r0shi gave some genuine ideas for fixing that problem, and it looks like you mostly ignored them.

It looks like you're trying to create a program that calculates the total grade for 3 exams. You seriously had something going when you created three 1d arrays. Congratz. Now you can get rid of your 2d array that you read into.

To read into each 2d array separately, you need to determine if the column divides by 3, and if not, what its remainder is. There is a convenient operator for doing this that looks like this: %. It spits out the remainder of a division. If the number divides perfectly, there is no remainder.
http://cplusplus.com/doc/tutorial/operators/

Use a switch statement to determine which array to write to.
http://cplusplus.com/doc/tutorial/control/

Also, your check grade function, I'm sorry to say, is very hard to understand. Use if-else statements, not nested if statements.
http://cplusplus.com/doc/tutorial/control/

Finally, your declarations are, sorry, quite messed up. Do not declare anything in your main() function. Put this: double exam1[100],exam2[100],exam3[100]; in place of the double exam[100][3]; that you can find at line 8. Also, in your function declarations and definitions, you can get rid of all the arguments (everything in between the parenthesis in lines 72, 27, 6, and 5). Also, have your functions return void, and get rid of all the return statements in your functions.

I hope this works, and I hope that you read that.

Keep trying.

EDIT: The elite and veterans of this forum will NEVER write out the whole solution to a problem.

-Albatross

Last edited on
Pages: 12