reading matrix from a file

So my lecturer gave me a a function to read a matrix from a file, but it is in C language, and I can't seem to change it to C++ language and get it to work, so I would really like to have your help with 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
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
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>

using namespace std;

string name;
long int n, optimum; 
long int **read_matrix(ifstream, long int);
long int **f;
long int **d;

int main()
{
	ifstream infile;
	infile.open("nug12.dat");
	cout <<"Name: ";
	infile >>name;
	cout <<name<<"\n";
	
	cout <<"Rows and Columns: ";
	infile >>n;
	cout <<n<<"\n";
	
	cout <<"Optimum solution: ";
	infile >>optimum;
	cout <<optimum<<"\n";
	
	d=read_matrix(infile, n);
	cout <<d;
	
return 0;
}

long int **read_matrix(ifstream input, long int n)
{

    /*    
    FUNCTION:       read instance matrices
    INPUT:          instance file name, instance size
    OUTPUT:         d-matrix and f-matrix
    (SIDE)EFFECTS:  none
    COMMENTS:       read the distance matrix and flow matrix
    */

  
	long int i, j;
	long int **matrix;
	for (i = 0; i < n; i++)
	{
		matrix[i] =(long int *)(matrix + n) + i*n;
    	for (j = 0; j < n; j++)
		{
			if(infile(input, "%ld", &matrix[i][j]) < 0)
			{
				printf("\n%ld",matrix[i][j]);
				fprintf(stderr,"error reading (%ld, %ld) in file", i, j);
				exit(1);
			}
		printf <<*matrix;
    	}
	}
    return matrix; 	
}


The original function coding was actually 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
int **read_matrix(FILE *input, long int size){

    /*    
    FUNCTION:       read instance matrices
    INPUT:          instance file name, instance size
    OUTPUT:         d-matrix and f-matrix
    (SIDE)EFFECTS:  none
    COMMENTS:       read the distance matrix and flow matrix
    */

  
  long int i, j;
  long int **matrix;

  

  for (i = 0; i < size; i++){
    matrix[i] = (long int *)(matrix + size) + i*size;
    for (j = 0; j < size; j++){
      if(fscanf(input, "%ld", &matrix[i][j]) < 0){
/*	printf("\n%ld", matrix[i][j]);*/
	fprintf(stderr, "error reading (%ld, %ld) in file", i, j);
	exit(1);
      }
//       printf("%ld ", matrix[i][j]);
    }
  }
  return matrix;
}


This is the file I'm reading from:
12
578
0 1 2 3 1 2 3 4 2 3 4 5
1 0 1 2 2 1 2 3 3 2 3 4
2 1 0 1 3 2 1 2 4 3 2 3
3 2 1 0 4 3 2 1 5 4 3 2
1 2 3 4 0 1 2 3 1 2 3 4
2 1 2 3 1 0 1 2 2 1 2 3
3 2 1 2 2 1 0 1 3 2 1 2
4 3 2 1 3 2 1 0 4 3 2 1
2 3 4 5 1 2 3 4 0 1 2 3
3 2 3 4 2 1 2 3 1 0 1 2
4 3 2 3 3 2 1 2 2 1 0 1
5 4 3 2 4 3 2 1 3 2 1 0

0 5 2 4 1 0 0 6 2 1 1 1
5 0 3 0 2 2 2 0 4 5 0 0
2 3 0 0 0 0 0 5 5 2 2 2
4 0 0 0 5 2 2 10 0 0 5 5
1 2 0 5 0 10 0 0 0 5 1 1
0 2 0 2 10 0 5 1 1 5 4 0
0 2 0 2 0 5 0 10 5 2 3 3
6 0 5 10 0 1 10 0 0 0 5 0
2 4 5 0 0 1 5 0 0 0 10 10
1 5 2 0 5 5 2 0 0 0 5 0
1 0 2 5 1 4 3 5 10 5 0 2
1 0 2 5 1 0 3 0 10 0 2 0

Thanks in advance! :)
And I sincerely apologize if there are lots of mistakes in the coding, I'm new to reading files and in using pointer :(
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
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
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

template<typename T>
vector< vector<T> > readMatrix( istream &in, int N )
{
   vector< vector<T> > M( N, vector<T>( N ) );
   for ( int i = 0; i < N; i++ )
   {
      for ( int j = 0; j < N; j++ ) in >> M[i][j];
   }
   return M;
}


template<typename T>
void writeMatrix( ostream &out, const vector< vector<T> > &M )
{
   for ( auto &row : M )
   {
      for ( auto e : row ) out << e << '\t';
      out << '\n';
   }
}


int main()
{
// ifstream in( "demo.txt" );
   istringstream in( "12                       \n"
                     "578                      \n"
                     "0 1 2 3 1 2 3 4 2 3 4 5  \n"
                     "1 0 1 2 2 1 2 3 3 2 3 4  \n"
                     "2 1 0 1 3 2 1 2 4 3 2 3  \n"
                     "3 2 1 0 4 3 2 1 5 4 3 2  \n"
                     "1 2 3 4 0 1 2 3 1 2 3 4  \n"
                     "2 1 2 3 1 0 1 2 2 1 2 3  \n"
                     "3 2 1 2 2 1 0 1 3 2 1 2  \n"
                     "4 3 2 1 3 2 1 0 4 3 2 1  \n"
                     "2 3 4 5 1 2 3 4 0 1 2 3  \n"
                     "3 2 3 4 2 1 2 3 1 0 1 2  \n"
                     "4 3 2 3 3 2 1 2 2 1 0 1  \n"
                     "5 4 3 2 4 3 2 1 3 2 1 0  \n"
                     "                         \n"
                     "0 5 2 4 1 0 0 6 2 1 1 1  \n"
                     "5 0 3 0 2 2 2 0 4 5 0 0  \n"
                     "2 3 0 0 0 0 0 5 5 2 2 2  \n"
                     "4 0 0 0 5 2 2 10 0 0 5 5 \n"
                     "1 2 0 5 0 10 0 0 0 5 1 1 \n"
                     "0 2 0 2 10 0 5 1 1 5 4 0 \n"
                     "0 2 0 2 0 5 0 10 5 2 3 3 \n"
                     "6 0 5 10 0 1 10 0 0 0 5 0\n"
                     "2 4 5 0 0 1 5 0 0 0 10 10\n"
                     "1 5 2 0 5 5 2 0 0 0 5 0  \n"
                     "1 0 2 5 1 4 3 5 10 5 0 2 \n"
                     "1 0 2 5 1 0 3 0 10 0 2 0 \n" );

   // Read
   int N, something;
   in >> N;
   in >> something;
   vector< vector<int> > A = readMatrix<int>( in, N );
   vector< vector<int> > B = readMatrix<int>( in, N );

   // Write
   writeMatrix<int>( cout, A );   cout << '\n';
   writeMatrix<int>( cout, B );
}
Last edited on
it was in c++. C does not have cout.
whether it was c-like c++ is another story.
Its more likely just dated code.
Last edited on
Hello kbklpl21,

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.
You can use the preview button at the bottom to see how it looks.

I found the second link to be the most help.

lastchance has a very nice program, but I am thinking that most of that code is beyond what you have learned. Still it is good for future reference.

The first question I have is do you need to use pointers for this?

As I look over the program I find that you have defined pointers, but do not give them any value.

The global variables, which you should avoid using, are likely to be initialized for you, but do not count on this.

In your first function you define long int **matrix,but never give it a value, i.e., an address or a size. the line if (infile(input, "%ld", &matrix[i][j]) < 0) you are trying to give an element of "matrix" a value, but "matrix" has no size, so it is unknown what bit of memory you are writing to.

It will take a little time to load your program and give it a test along with making some changes.

Hope that helps,

Andy

Edit: typo.
Last edited on
Hi Handy Andy, thanks for replying.
Yes I'm aware I don't need to use pointers for this, I've done it without using pointers, but this is an optimization problem coding, so the second matrix (the distance matrix) would change as I change the coding runs further, so I guess that's why my lecturer asked me to assign it using pointers.
Oh I thought what my lecturer meant from the 'if' part is for getting an invalid matrix or something like that.
So can I know if there are any other errors in the coding besides not assigning a value to **matrix?
Hi Jonnin, I meant the original function **read_matrix given by my lecturer that is from C, not the whole coding :)
Hi Lastchance, thanks for your help, but I think your coding is beyond my knowledge in C++ to understand :(
Never mind.

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

int **read_matrix( istream &input, int n );
void write_matrix( ostream &output, int **matrix, int n );

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

int main()
{
   int n, optimum;

   ifstream infile( "nug12.dat" );
   infile >> n;
   infile >> optimum;
   int **d = read_matrix( infile, n );
   int **f = read_matrix( infile, n );
   write_matrix( cout, d, n );   cout << '\n';
   write_matrix( cout, f, n );

   // You ought to delete d and f now
}

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

int **read_matrix( istream &input, int n )
{
   int **matrix = new int *[n];

   for ( int i = 0; i < n; i++ )
   {
      matrix[i] = new int[n];
      for ( int j = 0; j < n; j++ )
      {
         if ( !(input >> matrix[i][j]) )
         {
            cerr << "Error reading at " << i << ", " << j << '\n';
            exit( 1 );
         }
      }
   }
   return matrix;
}

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

void write_matrix( ostream &output, int **matrix, int n )
{
   for ( int i = 0; i < n; i++ )
   {
      for ( int j = 0; j < n; j++ ) output << matrix[i][j] << '\t';
      output << '\n';
   }
}


0	1	2	3	1	2	3	4	2	3	4	5	
1	0	1	2	2	1	2	3	3	2	3	4	
2	1	0	1	3	2	1	2	4	3	2	3	
3	2	1	0	4	3	2	1	5	4	3	2	
1	2	3	4	0	1	2	3	1	2	3	4	
2	1	2	3	1	0	1	2	2	1	2	3	
3	2	1	2	2	1	0	1	3	2	1	2	
4	3	2	1	3	2	1	0	4	3	2	1	
2	3	4	5	1	2	3	4	0	1	2	3	
3	2	3	4	2	1	2	3	1	0	1	2	
4	3	2	3	3	2	1	2	2	1	0	1	
5	4	3	2	4	3	2	1	3	2	1	0	

0	5	2	4	1	0	0	6	2	1	1	1	
5	0	3	0	2	2	2	0	4	5	0	0	
2	3	0	0	0	0	0	5	5	2	2	2	
4	0	0	0	5	2	2	10	0	0	5	5	
1	2	0	5	0	10	0	0	0	5	1	1	
0	2	0	2	10	0	5	1	1	5	4	0	
0	2	0	2	0	5	0	10	5	2	3	3	
6	0	5	10	0	1	10	0	0	0	5	0	
2	4	5	0	0	1	5	0	0	0	10	10	
1	5	2	0	5	5	2	0	0	0	5	0	
1	0	2	5	1	4	3	5	10	5	0	2	
1	0	2	5	1	0	3	0	10	0	2	0
Hi again Lastchance, is your function write_matrix just for printing the matrix? I tried removing the write_matrix function, and have

1
2
3
4
	long int **d=read_matrix(infile, n);
	cout << **d << endl;
	long int **f=read_matrix(infile, n);
	cout << **f << endl;

in my main function instead, but the output shows 0 for both
Yes, it is just for printing the matrix.
Can I know why I can't do as the coding I had above in the main function?
I also tried having the 'for' loop from your write_matrix function into the read_matrix function, but it won't work either. Can I know what's the difference?
kbklpl wrote:
Can I know why I can't do as the coding I had above in the main function?

Many computer languages allow you to output (and input) a whole matrix just by writing its name, but C++ won't. If you write cout << **d you will output just one element - the first element in the first row. In this case that happens to be 0.


kbklpl wrote:
I also tried having the 'for' loop from your write_matrix function into the read_matrix function, but it won't work either.

Then you have not coded it correctly.


There is a good tutorial on this site that includes flow control (including loops) and input/output. I would recommend spending some time on it.
http://www.cplusplus.com/doc/tutorial/

Last edited on
Oh you're right, I accidentally put the 'for' loop into the 'for' loop for reading the matrix, my bad.
Oh and another question, must the function of read_matrix be a pointer to pointer to int? Is it because we're returning a pointer to pointer to int value?
Each row is an array ... for which you need a pointer to an int (i.e. int*)
The set of rows is itself an array of rows ... for which you need a pointer.

Hence you need a pointer to a pointer of ints; i.e. int * *

But you could, of course, use vectors ....
Even for the function? I understand if it is just for the variable to save the matrix in, but I'm wondering if even the function itself needs to be a pointer to pointer.
If you are calculating something in the function and it needs to be sent back to the calling program then it will either have to be a function argument or the return value of the function. So one of those is going to be an int**.

Things are a little tidier if you have fixed-size arrays, but if you have dynamically allocated memory and you don't want to use vectors then you don't have much choice.


It's all so, so much easier in Fortran!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
program main
   implicit none
   integer N, optimum
   integer, allocatable :: d(:,:), f(:,:)
   character(len=80) fmt

   open( 10, file="nug12.dat" )
   read( 10, * ) N, optimum
   allocate( d(N,N), f(N,N) )
   read( 10, * ) d, f

   write( fmt, "( '( ', i0, '(i3,1x) )' )" ) N;
   write( *, fmt ) d;   write( *, * )
   write( *, fmt ) f
end program main
Topic archived. No new replies allowed.