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

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

本文关键字:为什么 2D 函数 数组 文件 弄清楚 读取 一行      更新时间:2023-10-16

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

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

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

和 B) 计算矩阵中的 1 个数。 所以上面的例子将返回 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 阅读器有关。

4 3
1 2 3 4

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

在评论中,你问

没有人有更好的方法将矩阵传递给count_ones方法?

  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.

你在最后一个 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[][] 作为函数参数,它会通过错误多维数组必须有除第一个之外的所有维度的边界

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

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

所以,在你发布错误之前我不知道错误是什么,但我知道为什么你的输出被过早切断。

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

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 离开了函数。

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

解决方案:只需将 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;

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