Continuing from our discussion in the comments, the biggest issue you are facing in being able to read and store A
and B
is the jumbled mixing or user-interface and code-implementation. (interface being how you interact with the user, implementation being the rest of your program) You want to keep interface and implementation separate.
Whether you display your text menu in a terminal where the user enters a number for the choice, or if your program selection is displayed in a window with check boxes next to the selection, your interface just returns what that choice was to your program to process. Separating your switch()
implementation from the Menu()
display will keep you from having to pass the arrays to Menu()
or declaring the variable within the menu display function. Instead, change the function type to int Menu()
and return the value of the menu selection for processing in your switch()
in main()
.
This allows you to declare your arrays in main()
and provide them to whatever function requires them without having to shoehorn all that logic into your menu-display function.
While we are on your Menu()
function, you must validate EVERY user input by checking the stream state. Otherwise you have no way of knowing if you have valid input, or if the user slipped and pressed 'r'
instead of '4'
. You must handle unrecoverable errors (badbit
), matching failure ('r'
instead of '4'
which sets failbit
) or the user manually canceling input by pressing Ctrl + d (Ctrl + z on windows).
Putting it altogether, your Menu()
function could be written as:
int Menu (void)
{
int mode = 0; /* (initialize all others is good practice) */
std::cout << "\nChoose the operation:\n"
<< " 1- Function to read the matrix A\n"
<< " 2- Function to read the matrix B\n"
<< " 3- Function to display content of a matrix A\n"
<< " 4- Function to display content of a matrix B\n"
<< " 5- Function to find the sum of A & B\n"
<< " 6- Function to find the product of A & B\n"
<< " 7- Function to find & display sum of rows & sum of cols. of a A\n"
<< " 8- Function to find & display sum of rows & sum of cols. of a B\n"
<< " 9- Function to find sum of diagonal elements A\n"
<< " 10- Function to find sum of diagonal elements B\n"
<< " 11- Function to find out transpose of A\n"
<< " 12- Function to find out transpose of B\n"
<< " 13- Exit \n\n"
<< "mode: ";
while (!(std::cin >> mode)) { /* require valid input, exit on badbit or eofbit */
if (std::cin.bad()) { /* handle unrecoverable error */
std::cerr << "unrecoverable stream error.\n";
return -1;
}
else if (std::cin.eof()) { /* handle manual EOF */
std::cout << "(user canceled input)\n";
return -1;
}
/* handle .fail() matching failure */
std::cerr << "error: invalid integer input.\n";
std::cin.clear(); /* clear error */
/* empty stdin */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
}
return mode;
}
(note: unrecoverable error and EOF
return a -1
to the caller, also note the use of std::basic_istream::ignore to empty all characters from stdin
in the event of a matching failure)
You will also notice the using namespace std;
had been removed, see Why is “using namespace std;” considered bad practice?.
With a few helpful constants defined at the top of your code:
static const int ROWS = 10,
COLS = ROWS,
EXIT = 13;
Your implementation handling the user selection in main()
could be:
do { /* loop continually until error or exit */
switch ((mode = Menu()))
{
case 1: validA = read (A, na, ma); break;
case 2: validB = read (B, nb, mb); break;
case 3: if (validA) printArr (A, na, ma); break;
case 4: if (validB) printArr (B, nb, mb); break;
case 5: if (validA && validB) S = sum (A, B, na, ma); break;
case 6:
case 7: /* case fall-through intentional until filled */
case 8:
case 9:
case 10:
case 11:
case 12: std::cout << mode << " not implemented\n"; break;
case 13: break;
default: std::cerr << "error: invalid menu selection.\n";
break;
}
} while (mode > 0 && mode != EXIT);
The rest of the changes to your code just involve shuffling the pieces around (refactoring) so that each takes the parameters they need. Since you output each matrix at various times, writing a void printArr()
function would prevent the duplication of code and also makes a convenient menu entry. A simple print array function could be:
void printArr (const int (*A)[COLS], const int N, const int M)
{
std::cout << "\nMatrix\n";
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++) {
std::cout << std::setw(4) << A[i][j];
}
std::cout << '\n';
}
}
(note: std::setw()
is used to set the width of each element output, adjust a needed)
Your biggest problem was with your sum()
function. As discussed in the comments, that was due to neither matrix A
or B
being stored in your program, and then user having to re-enter the values for each menu selection (not good). In main()
A
and B
will be declared as 10 x 10 Plain-Old-Arrays as also discussed in the comments due to your constraints (where you would normally use std::vector
or std::array
).
However, for sum()
, the parameter list will get a bit busy passing A
, B
, S
, and the dimensions, so instead, let's just allocate storage for S
in sum()
and return a pointer to the newly allocated storage, so you have the values for S
available back in main()
(you can do the same for your product()
, transpose()
, or diagonals()
functions as well. You can write sum()
as follows:
// sum part is no longer broken
int (*sum (int (*A)[COLS], int (*B)[COLS], int N, int M))[COLS]
{
int (*S)[COLS] = new int [ROWS][COLS]; /* allocaee storagre for ROWS x COLS */
for (int i = 0; i < ROWS; i++) /* zero elements in S */
std::fill_n (S[i], COLS, 0);
for (int i = 0; i < N; i++) /* sum values in A & B, result in S */
for (int j = 0; j < M; j++)
S[i][j] = A[i][j] + B[i][j];
printArr (S, N, M); /* output result */
return S; /* return pointer to S */
}
(note: a 2D array of int
has the type int (*)[10]
which is why you see the pointer for S
declared that way, and why you see the function sum()
also declared that way. You return a pointer-to-array-of int[10]
)
Also note the #include <algorithm>
for std::fill_n used to zero the newly allocated memory.
There is no need for a list of function prototypes at the beginning of your source file if you can simply order the functions in the proper order to satisfy their ependencies. In your code that basically meant swapping Read()
and read()
. Putting the entire program together, you could do:
#include <iostream>
#include <iomanip>
#include <limits>
#include <algorithm>
/* To avoid the use of global variables, you must pass the array
* and dimensions to every function that needs A, N, M. Array
* bound are fine as #define or static const int.
*/
static const int ROWS = 10,
COLS = ROWS,
EXIT = 13;
int Menu (void)
{
int mode = 0; /* (initialize all others is good practice) */
std::cout << "\nChoose the operation:\n"
<< " 1- Function to read the matrix A\n"
<< " 2- Function to read the matrix B\n"
<< " 3- Function to display content of a matrix A\n"
<< " 4- Function to display content of a matrix B\n"
<< " 5- Function to find the sum of A & B\n"
<< " 6- Function to find the product of A & B\n"
<< " 7- Function to find & display sum of rows & sum of cols. of a A\n"
<< " 8- Function to find & display sum of rows & sum of cols. of a B\n"
<< " 9- Function to find sum of diagonal elements A\n"
<< " 10- Function to find sum of diagonal elements B\n"
<< " 11- Function to find out transpose of A\n"
<< " 12- Function to find out transpose of B\n"
<< " 13- Exit \n\n"
<< "mode: ";
while (!(std::cin >> mode)) { /* require valid input, exit on badbit or eofbit */
if (std::cin.bad()) { /* handle unrecoverable error */
std::cerr << "unrecoverable stream error.\n";
return -1;
}
else if (std::cin.eof()) { /* handle manual EOF */
std::cout << "(user canceled input)\n";
return -1;
}
/* handle .fail() matching failure */
std::cerr << "error: invalid integer input.\n";
std::cin.clear(); /* clear error */
/* empty stdin */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
}
return mode;
}
void printArr (const int (*A)[COLS], const int N, const int M)
{
std::cout << "\nMatrix\n";
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++) {
std::cout << std::setw(4) << A[i][j];
}
std::cout << '\n';
}
}
bool Read (int (*A)[COLS], const int& N, const int& M)
{
for (int R = 0; R < N; R++)
for (int C = 0; C < M; C++)
{
std::cout << "Element ["<<R<<"]["<<C<<"] = ";
if (!(std::cin >> A[R][C])) {
std::cerr << "error: invalid Element ["<<R<<"]["<<C<<"]";
return false;
}
}
return true;
}
bool read (int (*A)[COLS], int& N, int& M)
{
std::cout << "\nEnter the value of n and m: ";
if (!(std::cin >> N >> M)) { /* validate EVERY input */
std::cerr << "error: invalid integer value for N or M, A not filled.\n";
return false;
}
return Read (A, N, M);
}
// sum part is no longer broken
int (*sum (int (*A)[COLS], int (*B)[COLS], int N, int M))[COLS]
{
int (*S)[COLS] = new int [ROWS][COLS]; /* allocaee storagre for ROWS x COLS */
for (int i = 0; i < ROWS; i++) /* zero elements in S */
std::fill_n (S[i], COLS, 0);
for (int i = 0; i < N; i++) /* sum values in A & B, result in S */
for (int j = 0; j < M; j++)
S[i][j] = A[i][j] + B[i][j];
printArr (S, N, M); /* output result */
return S; /* return pointer to S */
}
int main()
{
int A[ROWS][COLS] = {{0}}, /* initialize all plain-old-arrays */
B[ROWS][COLS] = {{0}},
na = 0, nb = 0, ma = 0, mb = 0, /* (and all variable ig good practice */
(*S)[COLS] = nullptr, /* pointer to allocated sum array */
mode = 0;
bool validA = false, /* flag - A/B filled w/o error */
validB = false;
do { /* loop continually until error or exit */
switch ((mode = Menu()))
{
case 1: validA = read (A, na, ma); break;
case 2: validB = read (B, nb, mb); break;
case 3: if (validA) printArr (A, na, ma); break;
case 4: if (validB) printArr (B, nb, mb); break;
case 5: if (validA && validB) S = sum (A, B, na, ma); break;
case 6:
case 7: /* case fall-through intentional until filled */
case 8:
case 9:
case 10:
case 11:
case 12: std::cout << mode << " not implemented\n"; break;
case 13: break;
default: std::cerr << "error: invalid menu selection.\n";
break;
}
} while (mode > 0 && mode != EXIT);
delete[] S; /* free storage allocated for S */
}
Example Use/Output
$ ./bin/matrix_poa
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 1
Enter the value of n and m: 3 3
Element [0][0] = 1
Element [0][1] = 2
Element [0][2] = 3
Element [1][0] = 4
Element [1][1] = 5
Element [1][2] = 6
Element [2][0] = 7
Element [2][1] = 8
Element [2][2] = 9
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 3
Matrix
1 2 3
4 5 6
7 8 9
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 2
Enter the value of n and m: 3 3
Element [0][0] = 9
Element [0][1] = 8
Element [0][2] = 7
Element [1][0] = 6
Element [1][1] = 5
Element [1][2] = 4
Element [2][0] = 3
Element [2][1] = 2
Element [2][2] = 1
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 4
Matrix
9 8 7
6 5 4
3 2 1
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 5
10 10 10
10 10 10
10 10 10
Choose the operation:
1- Function to read the matrix A
2- Function to read the matrix B
3- Function to display content of a matrix A
4- Function to display content of a matrix B
5- Function to find the sum of A & B
6- Function to find the product of A & B
7- Function to find & display sum of rows & sum of cols. of a A
8- Function to find & display sum of rows & sum of cols. of a B
9- Function to find sum of diagonal elements A
10- Function to find sum of diagonal elements B
11- Function to find out transpose of A
12- Function to find out transpose of B
13- Exit
mode: 13
That should at least get you started and show you how to handle storing both A
and B
as plain old arrays with automatic storage duration, but also show you how to allocate additional 2D arrays where needed. Look things over and let me know if you have questions.