g++ compiler error help, Matrix multiplication

Hello,

I am in need of some help on getting rid of these errors im getting. I am not sure how to fix them.

Also not sure how to open a file and send it to my void data1 and data2 with ifstream.

Error in g++ are.


a.cpp:11:12: error: variable or field ‘Data1’ declared void
 void Data1(ifstream&, int [][MAX_COLUMNS], int, int);
            ^
a.cpp:11:12: error: ‘ifstream’ was not declared in this scope
[ruizs10@bobby ~]$ g++ a.cpp
a.cpp:11:12: error: variable or field ‘Data1’ declared void
 void Data1(ifstream&, int [][MAX_COLUMNS], int, int);
            ^
a.cpp:11:12: error: ‘ifstream’ was not declared in this scope
a.cpp:11:12: note: suggested alternative:
In file included from /usr/include/c++/4.8.2/ios:38:0,
                 from /usr/include/c++/4.8.2/ostream:38,
                 from /usr/include/c++/4.8.2/iostream:39,
                 from a.cpp:1:
/usr/include/c++/4.8.2/iosfwd:157:34: note:   ‘std::ifstream’
   typedef basic_ifstream<char>   ifstream;
                                  ^
a.cpp:11:21: error: expected primary-expression before ‘,’ token
 void Data1(ifstream&, int [][MAX_COLUMNS], int, int);
                     ^
a.cpp:11:23: error: expected primary-expression before ‘int’
 void Data1(ifstream&, int [][MAX_COLUMNS], int, int);
                       ^
a.cpp:11:44: error: expected primary-expression before ‘int’
 void Data1(ifstream&, int [][MAX_COLUMNS], int, int);
                                            ^
a.cpp:11:49: error: expected primary-expression before ‘int’
 void Data1(ifstream&, int [][MAX_COLUMNS], int, int);
                                                 ^
a.cpp:12:12: error: variable or field ‘Data2’ declared void
 void Data2(ifstream&, int [][MAX_COLUMNS], int, int);
            ^
a.cpp:12:12: error: ‘ifstream’ was not declared in this scope
a.cpp:12:12: note: suggested alternative:
In file included from /usr/include/c++/4.8.2/ios:38:0,
                 from /usr/include/c++/4.8.2/ostream:38,
                 from /usr/include/c++/4.8.2/iostream:39,
                 from a.cpp:1:
/usr/include/c++/4.8.2/iosfwd:157:34: note:   ‘std::ifstream’
   typedef basic_ifstream<char>   ifstream;
                                  ^
a.cpp:12:21: error: expected primary-expression before ‘,’ token
 void Data2(ifstream&, int [][MAX_COLUMNS], int, int);
                     ^
a.cpp:12:23: error: expected primary-expression before ‘int’
 void Data2(ifstream&, int [][MAX_COLUMNS], int, int);
                       ^
a.cpp:12:44: error: expected primary-expression before ‘int’
 void Data2(ifstream&, int [][MAX_COLUMNS], int, int);
                                            ^
a.cpp:12:49: error: expected primary-expression before ‘int’
 void Data2(ifstream&, int [][MAX_COLUMNS], int, int);
                                                 ^
a.cpp: In function ‘int main(int, char**)’:
a.cpp:36:52: error: ‘Data1’ was not declared in this scope
   Data1(infile1, firstMatrix, rowFirst, columnFirst);
                                                    ^
a.cpp:50:68: error: ‘Data2’ was not declared in this scope
                Data2(infile2, secondMatrix, rowSecond, columnSecond);





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
                                                                                                                     

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>

const int MAX_ROWS = 10;
const int MAX_COLUMNS = 10;


void Data1(ifstream&, int [][MAX_COLUMNS], int, int);
void Data2(ifstream&, int [][MAX_COLUMNS], int, int);
void multiplyMatrices(int [][MAX_COLUMNS], int [][MAX_COLUMNS], int [][MAX_COLUMNS], int, int, int, int);
void display(int [][MAX_COLUMNS], int, int);

using namespace std;

int main(int argc, char **argv)
{
        if (argc != 3)
        {
                cout << "Error, must provide exactly two arguments!" << endl;
                return 0;
        }

        ifstream infile1; infile1.open(argv[2]);
        int firstMatrix[MAX_ROWS][MAX_COLUMNS];
        int rowFirst = 0, columnFirst = 0;

        if (!infile1)
        {
                cout << "Error, file could not be opened!" << endl;
                return 0;
        }
        else
                Data1(infile1, firstMatrix, rowFirst, columnFirst);

        infile1.close();

        ifstream infile2; infile2.open(argv[3]);
        int secondMatrix[MAX_ROWS][MAX_COLUMNS];
        int rowSecond = 0, columnSecond = 0;

        if (!infile2)
        {
                cout << "Error, file could not be opened!" << endl;
                return 0;
        }
        else
               Data2(infile2, secondMatrix, rowSecond, columnSecond);

        infile2.close();

        int mult[MAX_ROWS][MAX_COLUMNS];

        if (columnFirst != rowSecond)
        {
                cout<<"Error: Matrices cannot be multiplied!";
        }
        else
        {
                multiplyMatrices(firstMatrix, secondMatrix, mult, rowFirst,
                                 columnFirst, rowSecond, columnSecond);
                display(mult, rowFirst, columnSecond);
        }

        return 0;
}


void Data1(ifstream& infile1, int firstMatrix[][MAX_COLUMNS], int rowFirst, int columnFirst)
{

   while (!infile1.eof())
  {

      while(infile1 >> firstMatrix[rowFirst][columnFirst++]);

      columnFirst--;
      rowFirst++;
  }

}

void Data2(ifstream& infile2,int secondMatrix[][MAX_COLUMNS], int rowSecond, int columnSecond)
{


   while (!infile2.eof())
  {

      while(infile2 >> secondMatrix[rowSecond][columnSecond++]);
      columnSecond--;
      rowSecond++;
  }

}


void multiplyMatrices(int firstMatrix[][MAX_COLUMNS], int secondMatrix[][MAX_COLUMNS], int mult[][MAX_COLUMNS], 
                      int rowFirst, int columnFirst, int rowSecond, int columnSecond)
{

        // Initializing elements of matrix mult to 0.
        for(int i = 0; i < rowFirst; ++i)
        {
                for(int j = 0; j < columnSecond; ++j)
                {
                        mult[i][j] = 0;
                }
        }

        // Multiplying matrix firstMatrix and secondMatrix and storing in array mult.
        for(int i = 0; i < rowFirst; ++i)
        {
                for(int j = 0; j < columnSecond; ++j)
                {
                        for(int k = 0; k<columnFirst; ++k)
                        {
                                mult[i][j] += firstMatrix[i][k] * secondMatrix[k][j];
                        }
                }
        }
}


void display(int mult[][MAX_COLUMNS], int rowFirst, int columnSecond)
{

        for(int i = 0; i < rowFirst; ++i)
        {
                for(int j = 0; j < columnSecond; ++j)
                {
                        cout<< '\t' << mult[i][j] << '\t';
                        if(j == columnSecond - 1)
                                cout << endl;
                }
        }
}
Last edited on
I think you just need to move the using namespace std to just after the includes (before the prototypes).
Or you could write std::ifstream.
Yes that fixed all of the compiler errors, it was the namespace std. now for some reason it is not outputting the results when i try to output it out of main.

i also attempted using the display function i made above but that did not help.
1
2
3
4
5
6
7
8
9
10
11
12
13
void display(int mult[][MAX_COLUMNS], int rowFirst, int columnSecond)
{

        for(int i = 0; i < rowFirst; ++i)
        {
                for(int j = 0; j < columnSecond; ++j)
                {
                        cout<< '\t' << mult[i][j] << '\t';
                        if(j == columnSecond - 1)
                                cout << endl;
                }
        }
}


here is the updated code that i shorten without the display function.

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

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>

using namespace std;

const int MAX_ROWS = 10;
const int MAX_COLUMNS = 10;

void Data(ifstream&, int [][MAX_COLUMNS], int, int, ifstream&, int [][MAX_COLUMNS], int, int);
void multiplyMatrices(int [][MAX_COLUMNS], int [][MAX_COLUMNS], int [][MAX_COLUMNS], int, int, int, int);
void display(int [][MAX_COLUMNS], int, int);

int main(int argc, char **argv)
{
        if (argc != 3)
        {
                cout << "Error, must provide exactly two arguments!" << endl;
                return 0;
        }

        ifstream infile1(argv[1]); ifstream infile2(argv[2]);
        int firstMatrix[MAX_ROWS][MAX_COLUMNS], secondMatrix[MAX_ROWS][MAX_COLUMNS];
        int rowFirst = 0, columnFirst = 0, rowSecond = 0, columnSecond = 0;

        if (!infile1)
        {
                cout << "Error, file could not be opened!" << endl;
                return 0;
        }
         if (!infile2)
        {
                cout << "Error, file could not be opened!" << endl;
                return 0;
        }
        Data(infile1, firstMatrix, rowFirst, columnFirst,
             infile2, secondMatrix, rowSecond, columnSecond);

        infile1.close();
        infile2.close();

        int mult[MAX_ROWS][MAX_COLUMNS];

        multiplyMatrices(firstMatrix, secondMatrix, mult, rowFirst,
                         columnFirst, rowSecond, columnSecond);
        //displays the mult array. 
       for(int i = 0; i < rowFirst; ++i)
        {
                for(int j = 0; j < columnSecond; ++j)
                {
                        cout<< '\t' << mult[i][j] << '\t';
                        if(j == columnSecond - 1)
                                cout << endl;
                }
        }


        return 0;
}


void Data(ifstream& infile1, int firstMatrix[][MAX_COLUMNS], int rowFirst, int columnFirst, 
           ifstream& infile2,int secondMatrix[][MAX_COLUMNS], int rowSecond, int columnSecond)
{

   while (!infile1.eof())
  {

      while(infile1 >> firstMatrix[rowFirst][columnFirst++]);

      columnFirst--;
      rowFirst++;
  }


   while (!infile2.eof())
  {

      while(infile2 >> secondMatrix[rowSecond][columnSecond++]);

      columnSecond--;
      rowSecond++;
  }

}


void multiplyMatrices(int firstMatrix[][MAX_COLUMNS], int secondMatrix[][MAX_COLUMNS], int mult[][MAX_COLUMNS], 
                      int rowFirst, int columnFirst, int rowSecond, int columnSecond)
{
       if (columnFirst != rowSecond)
        {
                cout<<"Error: Matrices cannot be multiplied!";
        }
        else
        {
                // Initializing elements of matrix mult to 0.
                for(int i = 0; i < rowFirst; ++i)
                {
                        for(int j = 0; j < columnSecond; ++j)
                        {
                                mult[i][j] = 0;
                        }
                }

                // Multiplying matrix firstMatrix and secondMatrix and storing in array mult.
                for(int i = 0; i < rowFirst; ++i)
                {
                        for(int j = 0; j < columnSecond; ++j)
                        {
                                for(int k = 0; k<columnFirst; ++k)
                                {
                                        mult[i][j] += firstMatrix[i][k] * secondMatrix[k][j];
                                }
                        }
                }

        }
}
In Data (lines 74 and 84), you are saying
 
     columnFirst--;

but it needs to be
 
     columnFirst = 0;


And it's pretty weird to be passing in what are essentially just local variables. Just make them local:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Data(ifstream& infile1, int firstMatrix[][MAX_COLUMNS], 
          ifstream& infile2,int secondMatrix[][MAX_COLUMNS])
{
    int row = 0, column = 0;
    while (!infile1.eof())
    {
        while(infile1 >> firstMatrix[row][column++]) ;
        column = 0;
        row++;
    }

    row = column = 0;
    while (!infile2.eof())
    {
        while(infile2 >> secondMatrix[row][column++]);
        column = 0;
        row++;
    }
}



EDIT: I see now that you were attempting to return the sizes of the matrices through those inputs. You would need to make them references to do that, otherwise the changes aren't seen in the caller.

Please show the exact format of the input files.
If it's one row of numbers per line and you are trying to determine the number of columns then you should read it line by line, maybe something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void ReadMatrix(ifstream& infile1, int firstMatrix[][MAX_COLUMNS],
                int &rows, int &columns)
{
    int row = 0, col = 0;
    string line;
    while (getline(infile1, line)) {
        istringstream sin(line);
        while (sin >> mat[row][col++]) ;
        columns = col;
        ++row;
        col = 0;
    }
    rows = row;
}

// call it like this
ReadMatrix(infile1, firstMatrix, rowFirst, columnFirst);
ReadMatrix(infile2, secondMatrix, rowSecond, columnSecond);

Last edited on
thank you for your help, the test files would like this.

for data 1


1 2      3
4        5   6


for data 2


7  8
9      10
11          12


should i also move the logic of if the two matrices are not the same size to only output the text of "Error: Matrices cannot be multiplied!"



Is there any reason the number are spread out like that?
Is there an empty line at the beginning (or end) or the file?

Try reading them like this. Maybe just print them out at first after reading them.
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
#include <sstream> // istringstream
#include <cstdlib>  // exit

void ReadMatrix(ifstream& infile1, int firstMatrix[][MAX_COLUMNS],
                int &rows, int &columns)
{
    int row = 0, col = 0, ncols = 0;
    string line;
    while (getline(infile1, line)) {
        if (line.find_first_not_of(" \t\r\n") == line.npos)
            continue; // skip empty lines
        istringstream sin(line);
        while (sin >> mat[row][col++]) ;
        if (ncols == 0)
            ncols = col;
        else if (col != ncols) {
            cerr << "Number of columns doesn't match.\n";
            exit(1);
        }
        ++row;
        col = 0;
    }
    columns = ncols;
    rows = row;
}

// call like this
ReadMatrix(infile1, firstMatrix, rowFirst, columnFirst);
ReadMatrix(infile2, secondMatrix, rowSecond, columnSecond);


To multiply matrices the number of columns of the first needs to match the number of rows of the second (I think I have that the right way around). So it they don't match, you can't multiply them.
The possibility of unknown number of rows and columns in the files just screams vectors ;D You also would want to re-use the method that reads the data. Throw an error if something is amiss, because it's fatal to the rest of your program (don't try to display the un-multiplied result, for example, if rows or columns of the other vectors are not equal). Let the user catch the error if he/she really wants to proceed.

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

using namespace std;

// Read file of unknown rows/columns into new 2D vector
vector<vector<int>> ReadData(ifstream& ifs)
{
    vector<vector<int>> mat;
    string line;
    int n;
    while (ifs)
    {
        vector<int> v;
        getline(ifs, line);
        istringstream iss(line);
        while (iss >> n)
            v.push_back(n);
            
        if (!v.empty()) // Avoid trailing newline
            mat.emplace_back(v);
    }
    return mat;
}

// Show contents of a 2D vector
void Show(const vector<vector<int>>& mat)
{
    for (auto& row : mat)
    {
        for (auto& n : row)
            cout << setw(6) << n;
        cout << endl;
    }
}

// Multply two 2D vectors
vector<vector<int>> Multiply(const vector<vector<int>>& mat, 
                             const vector<vector<int>>& mat2)
{
    if (mat.size() != mat2.size())
        throw out_of_range("Error: matrix rows different sizes; unable to multiply.");

    if (mat[0].size() != mat2[0].size())
        throw out_of_range("Error: matrix columns different sizes; unable to multiply.");

    vector<vector<int>> m(mat.size(), vector<int>(mat[0].size()) );
    for (int r=0; r<mat.size(); ++r)
        for (int c=0; c<mat[r].size(); ++c)
            m[r][c] = mat[r][c] * mat2[r][c];

    return m;
}

int main(int argc, char **argv)
{
    string file("mat.txt");
    string file2("mat2.txt");
    ifstream ifs(file);
    ifstream ifs2(file2);

    if (!ifs)
    {
        cout << "Error, \"" << file << "\" could not be opened!" << endl;
        return -1;
    }
     if (!ifs2)
    {
        cout << "Error, \"" << file2 << "\" could not be opened!" << endl;
        return -2;
    }
    
    cout << "Mat:" << endl;
    auto mat = ReadData(ifs);
    Show(mat);
    cout << endl;
    
    cout << "Mat2:" << endl;
    auto mat2 = ReadData(ifs2);
    Show(mat2);
    cout << endl;
    
    cout << "Multiplied:" << endl;
    auto mult = Multiply(mat, mat2);
    Show(mult);
    cout << endl;

    return 0;
}


example output for 7x10 multiplication, running at https://repl.it/repls/FirstRawTechnician :
Mat:
    39    50    88    58    33     8    68    74    52    36
    73    80    28    84    17    25    70    34    67    10
    33    12    89    73    57    55    55    37    64    12
    98    48    70     6    86    76    83    66    50    26
    84    99    49    66    29    84    48    94    19    56
    95    48    13    23    10     5    93    55    96    42
    17    59    96    67    52    98    10    45    87    96

Mat2:
    11    38    92     7    87    47    66    58    73    31
    10     4    68    17    26    47    88    36    41    85
    17    72    78    72    74    66    30    59    77    59
    41    86    41    53    51    81    26    25    62    75
    97     7     1    59    87    59    81    63    55    23
    73    50    86    76    77    57    28    35    81    80
    72    88    22    65    55    79    30    76    84    43

Multiplied:
   429  1900  8096   406  2871   376  4488  4292  3796  1116
   730   320  1904  1428   442  1175  6160  1224  2747   850
   561   864  6942  5256  4218  3630  1650  2183  4928   708
  4018  4128  2870   318  4386  6156  2158  1650  3100  1950
  8148   693    49  3894  2523  4956  3888  5922  1045  1288
  6935  2400  1118  1748   770   285  2604  1925  7776  3360
  1224  5192  2112  4355  2860  7742   300  3420  7308  4128
thank you for all the replies, and i am not allowed to use Vectors yet. It had to be with a 2D array.

i used the istringstream sin(line); method and it fixed the issues.
Topic archived. No new replies allowed.