【问题标题】:Matrix Reading C++矩阵读取 C++
【发布时间】:2021-04-03 01:16:05
【问题描述】:

所以基本上我正在尝试创建一个对矩阵进行多项操作的函数。作为第一步,我需要一个读取函数和写入函数,但问题是我在读取函数时遇到了问题。它应该返回数据并保存它,但我不确定我将如何使用指针。此外,总和部分也被破坏了。它不是将两个矩阵相加,而是将第二个矩阵添加到第一个矩阵的末尾,但我认为这也是由 read 函数的问题引起的。

 #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;
}

【问题讨论】:

  • 哇...另请参阅:What should main() return in C and C++?,为什么您在 C++ 中使用普通旧数组而不是 std::vector
  • 这是我的学校任务。通常,老师会为我们提供上述操作的所有功能,但他的功能确实被破坏了,我正在尝试自己创建所有功能,这就是我使用数组的原因。而且他只是不回复我们的电子邮件,因为他不是一位好老师,所以我试图在这里找到解决方案。
  • 我不打算返回主目录。我需要使用一个在另一个函数中读取的数组。
  • 好吧,这很有道理,要么你的教授想让你学习遗留代码(或者他是从 1991 年的教学大纲开始教学)
  • 问题是您没有存储任何数据。这意味着您必须为每个菜单操作重新输入数据。这是非常低效的。至少,您应该在main() 中声明AB,然后将它们传递给read() 进行填充,同时传递给sum() 进行计算。这将需要单独的菜单条目,例如"1- read the matrix A\n""2- read the matrix B\n"。那么你必须解决AB 需要单独的NM 的问题,除非你强制用户填写10x10。您必须验证每个用户输入,例如if (!(cin &gt;&gt; mode)) { /* handle error */ }

标签: c++ matrix multidimensional-array


【解决方案1】:

继续我们在 cmets 中的讨论,您在读取和存储 AB 时面临的最大问题是混乱的混合或用户界面和代码实现。 (接口是您与用户交互的方式,实现是程序的其余部分)您希望将接口和实现分开。

无论您是在用户输入选项的终端中显示文本菜单,还是在选择旁边带有复选框的窗口中显示您的程序选择,您的界面只会将选择返回给您程序来处理。将switch() 实现与Menu() 显示分开将使您不必将数组传递给Menu() 或在菜单显示函数中声明变量。相反,将函数类型更改为int Menu() 并返回菜单选择的值,以便在switch() 中处理main()

这允许您在main() 中声明您的数组并将它们提供给任何需要它们的功能,而无需将所有逻辑硬塞到您的菜单显示功能中。

当我们使用您的Menu() 函数时,您必须通过检查流状态来验证每个用户输入。否则你无法知道你是否有有效的输入,或者用户是否滑动并按下'r'而不是'4'。您必须处理不可恢复的错误 (badbit)、匹配失败 ('r' 而不是设置 failbit'4') 或用户通过按 Ctrl + d (Ctrl + z在窗户上)。

总而言之,您的Menu() 函数可以写成:

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;
}

(注意: 不可恢复的错误和EOF-1 返回给调用者,还要注意使用std::basic_istream::ignore 来清空stdin 中的所有字符以防匹配失败)

您还会注意到using namespace std; 已被删除,请参阅Why is “using namespace std;” considered bad practice?

在代码顶部定义了一些有用的常量:

static const int ROWS = 10,
                 COLS = ROWS,
                 EXIT = 13;

您在main() 中处理用户选择的实现可能是:

    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);

对代码的其余更改仅涉及对各个部分进行改组(重构),以便每个部分都获取所需的参数。由于您在不同时间输出每个矩阵,因此编写 void printArr() 函数可以防止代码重复,也可以方便地进入菜单。一个简单的打印数组函数可以是:

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';
    }
}

注意:std::setw()用于设置每个元素输出的宽度,需要调整一个)

你最大的问题是你的sum() 函数。正如 cmets 中所讨论的,这是由于矩阵 AB 都没有存储在您的程序中,然后用户必须为每个菜单选择重新输入值(不好)。在 main() 中,AB 将被声明为 10 x 10 Plain-Old-Arrays,由于您的限制(通常使用 std::vectorstd::array),在 cmets 中也进行了讨论。

但是,对于sum(),参数列表会有点忙于传递ABS 和维度,因此,我们只需在sum() 中为S 分配存储空间并返回一个指向新分配的存储的指针,这样您就可以在main() 中获得S 的值(您也可以对product()transpose()diagonals() 函数执行相同的操作。您可以写sum()如下:

// 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 的二维数组的类型为 int (*)[10],这就是为什么您会看到 S 的指针以这种方式声明的原因,以及您看到函数 sum() 的原因也这样声明。你返回一个 pointer-to-array-of int[10])

还要注意 #include &lt;algorithm&gt;std::fill_n 用于将新分配的内存归零。

如果您可以简单地以正确的顺序对函数进行排序以满足它们的依赖关系,则不需要在源文件的开头列出函数原型。在您的代码中,这基本上意味着交换 Read()read()。将整个程序放在一起,您可以这样做:

#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 */
}

使用/输出示例

$ ./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

这至少应该可以帮助您入门,并向您展示如何将 AB 存储为具有自动存储持续时间的普通旧数组,同时也向您展示如何在需要时分配额外的 2D 数组。如果您有任何问题,请仔细查看并告诉我。

【讨论】:

    【解决方案2】:

    请保持您的帖子回答一个问题。我将在下面检查您的 Read() 函数:

    根据您要执行的操作,您必须利用动态内存分配。

    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;
    
            }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-06
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多