2

So basically I am trying to create a function with multiple operations about matrices. As the first step, I need a read function and write function but the problem is I am having trouble with read function. It should return the data and save it but I am not sure how I am going to use pointers. Also, sum part is broken as well. Instead of sum up two matrices, it adds the second one to the end of the first one but I think this is also caused by the problem at read function.

 #include <iostream>
using namespace std;

void Menu(void);
void Read(int A[10][10], int N, int M);
void read(void);
void sum(void);

void Menu(void)
{
    int mode;
    cout << "Choose the operation: \n1- Function to read the matrix \n";
    cout << "2- Function to display content of a matrix \n";
    cout << "3- Function to find the sum of two matrixes \n";
    cout << "4- Function to multiply two matrixes \n";
    cout << "5- Function to find & display sum of rows & sum of cols. of a matrixes \n";
    cout << "6- Function to find sum of diagonal elements of a square matrix \n";
    cout << "7- Function to find out transpose of a matrix \n";
    cout << "8- Exit \n";
    cin >> mode;
    switch(mode) 
    {
        case 1: read(); break;
        case 2: break;
        case 3: sum(); break;   
    }
    
    cout << "1 - Repeat? \n2 - Exit?\n";
    cin >> mode;
    switch(mode)
    {
        case 1: Menu(); break;
        case 2: break;
    }   
}

void read(void)
{
    int A[10][10],N,M,i,j;
    cout << "Enter the value of n and m: ";
    cin >> N >> M;
    Read(A,N,M);
    
}
void Read(int A[10][10], int N, int M)
{
    for(int R=0; R<N; R++)
        for(int C=0; C<M; C++)
        {
        cout<<"Element ["<<R<<"]["<<C<<"] = ";
        cin>>A[R][C];
        }
    cout << endl;
    cout<<"You have entered following matrix"<<endl;
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<M; j++)
            cout << A[i][j]<< " ";
        cout << endl;   
    }   
}

// sum part is broken
void sum()
{
    int A[10][10],B[10][10],N,M,i,j;
    int S[10][10];
    cout << "Enter the value of n and m: ";
    cin >> N >> M;
    Read(A,N,M);
    Read(B,N,M);
    for(int i=0; i<N; i++)
        for(int j=0; j<M; j++)
            S[i][j] = A[i][j] + B[i][j];
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<M; j++)
            cout << B[i][j]<< " ";
        cout << endl;   
    }           
}

int main()
{
    
    Menu(); 
    return 0;
}
Raw Anger
  • 23
  • 5
  • 1
    Whoa... See also: [What should main() return in C and C++?](http://stackoverflow.com/questions/204476/) and why are you using plain-old-arrays in C++ and not [std::vector](https://en.cppreference.com/w/cpp/container/vector)? – David C. Rankin Apr 03 '21 at 01:20
  • It is for my school task. Normally the teacher gives us all functions for the above operations but his functions are really broken I am trying to create all of them myself that's why I am using arrays. And he just doesn't give respond to our emails because he is not a good teacher so I am trying to find a solution here. – Raw Anger Apr 03 '21 at 02:04
  • I am not looking to return for main. I need to use an array one read in another function. – Raw Anger Apr 03 '21 at 02:07
  • Okay, that makes sense, either your professor wants you to learn about Legacy code (or he is teaching from a syllabus from 1991) – David C. Rankin Apr 03 '21 at 02:08
  • The problem is you are not storing any of the data. That mean you have to re-enter the data for every menu operation. That is horribly inefficient. At minimum, you should declare `A` and `B` in `main()` and then pass each to `read()` for filling and both to `sum()` for computation. This will require separate menu entries for, e.g. `"1- read the matrix A\n"` and `"2- read the matrix B\n"`. Then you have to problem of needing separate `N` and `M` for `A` and `B` unless you force the user to fill 10x10. You must validate EVERY user input, e.g. `if (!(cin >> mode)) { /* handle error */ }` – David C. Rankin Apr 03 '21 at 08:10
  • Okay yes that is exactly my problem and I know that is my problem but I don't know how to store that matrices. I only need two matrices at the same time for sum up and multiplication but I think I have a solution for that if I can manage to solve storing. – Raw Anger Apr 03 '21 at 22:55

2 Answers2

1

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.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
-1

Please keep your post to one question. I will examine your Read() function below:

Based on what you're trying to do, you must utilize dynamic memory allocation.

void read(int** A, int N, int M);
void print_matrix(int** A, int N, int M);

int main() {

    int nrows = 0, ncolumns = 0;
    
    std::cout << "Enter number of rows: ";
    std::cin >> nrows;

    std::cout << "Enter number of columns: ";
    std::cin >> ncolumns;

    int** matrix = new int*[nrows];

    // dynamically allocate the nrows, each of size ncolumns
    for(int i = 0; i < nrows; ++i) {
        matrix[i] = new int[ncolumns];
    }

    read(matrix, nrows, ncolumns);
    print_matrix(matrix, nrows, ncolumns);

    // deallocate memory for the matrix
    // after your program is finished
    for(int i = 0; i < nrows; ++i) {
        delete[] matrix[i];
        matrix[i] = nullptr;
    }

    delete[] matrix;
    matrix = nullptr;

}

void read(int** A, int N, int M) {

    for(int i = 0; i < N; ++i) {

        std::cout << "Enter " << M << " values for row " << i + 1
                  << " separated by spaces: ";
        
        for(int j = 0; j < M; ++j) {
            std::cin >> A[i][j];
        }

    }

}

// this function is used to verify that the matrix
// was read in correctly
void print_matrix(int** A, int N, int M) {

    for(int i = 0; i < N; ++i)
        for(int j = 0; j < M; ++j) {

            std::cout << std::right << std::setw(7) << A[i][j];
            if((j + 1) % M == 0) std::cout << std::endl;

        }

}
Mutating Algorithm
  • 2,604
  • 2
  • 29
  • 66