无法弄清楚为什么只从文件中读取一行矩阵以及为什么我不能将二维数组传递给函数

Can't figure out why only one line of matrix is being read from a file and why I can't pass a 2D array to a function

我已经为此苦苦挣扎了大约一个小时,所以我转向万能的互联网实体寻求帮助。

我正在尝试编写一个程序,它将 A) 按照以下格式从 txt 文件中读取矩阵,其中第一个数字是列 (4),第二个数字是行 (3)矩阵。每行数字对应矩阵中的一行。

4 3
1 2 3 4
0 1 2 7
4 1 9 2

和 B) 计算矩阵中 1 的个数。所以上面的例子会 return 3. 我的代码在下面。

#include <iostream>
#include <fstream>
#include <string>


using namespace std;

void count_ones(int matrix[][], int rows, int columns)
{

int count = 0;

for(int i = 0; i < rows; i++)
{
        for( int j = 0; j < columns; j++)
        {
                if( matrix[i][j] == 1)
                { count++;}
        }
}

cout << "There are " << count << " ones in this matrix.";
}

int main(int argc, char* argv[])
{

int rows, columns;
string file_name = argv[1];

ifstream reader("m1.txt");

reader >> columns;
reader >> rows;

int matrix[rows][columns];

for(int i = 0; i < rows; i++)
{
        for(int j = 0; j < columns; j++)
        {
          reader >>  matrix[i][j];
        }
}


cout << columns << " " << rows;
cout << endl;
for( int k = 0; k < rows; k++) {
      for( int l = 0; l < columns; l++)
         cout << matrix[k][l] << " ";
      cout << endl;

reader.close();

count_ones(matrix, rows,columns);
return 0;
}
}

现在我有两个问题。我用来打印我从 "m1.txt" 文件中读取的矩阵的代码只打印了前两行,我完全不知道是什么导致了这个,但我猜它有一些事情要做与我的 ifstream reader.

4 3
1 2 3 4

其次,当我尝试将我的矩阵传递给我的 count_ones 函数时,我遇到了一堆我不明白的错误。我对 C++ 不是很在行,所以我很感激能得到的所有帮助。

在评论中,您提问

Does anyone have a better way to pass the matrix to the count_ones method?

  1. 不要使用

    int matrix[rows][columns];
    

    这不是标准的 C++。它作为扩展被一些编译器支持。

  2. 使用

    std::vector<std::vector<int>> matrix;
    

    您可以使用

    使用正确的行和列大小对其进行初始化
    std::vector<std::vector<int>> matrix(rows, std::vector<int>(columns));
    
  3. 更改 count_ones 的声明以接受 std::vector<std::vector<in>>

    int count_ones(std::vector<std::vector<in>> const& matrix);
    

    相应地更新其实现。


改进建议

您可以通过使用辅助函数将矩阵写入 cout.

来避免将结束 } 放在错误位置的错误
std::ostream& operator<<(std::ostream& out, std::vector<int> const& row)
{
   for ( int item : row )
      out << item << " ";
   return out;
}

std::ostream& operator<<(std::ostream& out, std::vector<std::vector<int>> const& matrix)
{
   for ( auto const& row : matrix )
      out << row << std::endl;
   return out;
}

然后使用

std::cout << matrix;

main.

所以,直到你 post 我才知道错误是什么,但我知道为什么你的输出被过早地切断了。

所以,回顾一下,让我们再次查看您的代码(相关部分":

cout << columns << " " << rows;
cout << endl;
for( int k = 0; k < rows; k++) {
    for( int l = 0; l < columns; l++) /* { */
        cout << matrix[k][l] << " ";
    /* } */
    cout << endl;

    reader.close();

    count_ones(matrix, rows,columns);
    return 0;
}

我对其进行了缩进以便于阅读并添加了注释大括号,这样更清楚什么是由什么执行的。

现在,输出:

4 3
1 2 3 4

好的,现在让我们分解一下发生了什么。

cout << columns << " " << rows;
cout << endl;

这是创建行:

4 3

到目前为止还不错吧?

现在,我们进入lop:

for( int k = 0; k < rows; k++) {
    for( int l = 0; l < columns; l++) /* { */
        cout << matrix[k][l] << " ";
    /* } */
    cout << endl;

得到这个:

1 2 3 4

这必须是矩阵的第一行。

执行更多代码:

reader.close();

count_ones(matrix, rows,columns);

这与您的问题无关。

现在这个:

    return 0;
}

糟糕!我们刚刚通过调用 return.

离开了函数

循环将不再执行,因为 我们通过 returning 提前终止了它,只输出矩阵的第一行。

解决方案: 只需将 return 语句移到循环外,如下所示:

cout << columns << " " << rows;
cout << endl;
for( int k = 0; k < rows; k++) {
    for( int l = 0; l < columns; l++) /* { */
        cout << matrix[k][l] << " ";
    /* } */
    cout << endl;

    reader.close();

    count_ones(matrix, rows,columns);
}
return 0;

这应该可以解决问题。

最后,一些友好的建议,采纳 Sami Kuhmonen 的建议并缩进您的代码。它使阅读和捕捉这样的东西变得更容易。

编辑: 还有一点,如 R.k。 Lohana 提到,您可能也想将这些行从循环中拉出来:

    reader.close();

    count_ones(matrix, rows,columns);

像这样:

for( int k = 0; k < rows; k++) {
    for( int l = 0; l < columns; l++) /* { */
        cout << matrix[k][l] << " ";
    /* } */
    cout << endl;

}

reader.close();

count_ones(matrix, rows,columns);

return 0;

因为您可能只想执行一次而不是多次。

你在最后一个for循环中犯了一个错误。

for( int k = 0; k < rows; k++) {
      for( int l = 0; l < columns; l++)
         cout << matrix[k][l] << " ";
      cout << endl;

reader.close();

count_ones(matrix, rows,columns);
return 0;
}
}

应该是这样的

for( int k = 0; k < rows; k++) {
      for( int l = 0; l < columns; l++)
         cout << matrix[k][l] << " ";
      cout << endl;
}

reader.close();

count_ones(matrix, rows,columns);
return 0;
}

因此,代码中的外部 for 循环仅运行一次,并且仅打印矩阵的第一行。

编辑: 还有一些要更正的地方。您不能将 matix[][] 用作函数参数,它将通过错误 multidimensional array must have bounds for all dimensions except the first

您可以使用双指针来完成这项工作。将检查函数声明更改为 this

void count_ones(int **matrix, int rows, int columns)

替换

int matrix[rows][columns];

int **matrix = (int **)malloc(sizeof(int *)*columns);
for(int i=0; i < columns; i++)
    *(matrix + i) = (int *)malloc(sizeof(int)*rows);

而且代码应该很有魅力。并且还删除了这一行,它是多余的,因为 file_name 没有被使用。

string file_name = argv[1];