Не могу понять, почему из файла читается только одна строка матрицы и почему я не могу передать двумерный массив в функцию - PullRequest
0 голосов
/ 26 февраля 2019

Я боролся за это уже около часа, поэтому я обращаюсь ко всемогущему существу - Интернету за помощью.

Я пытаюсь написать программу, которая будет A) читатьматрица из текстового файла в следующем формате, где первое число - столбцы (4), а второе число - строки (3) в матрице.И каждая строка чисел соответствует строке в матрице.

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

и B) вычислить количество единиц в матрице.Таким образом, приведенный выше пример вернет 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 ++, поэтому я был бы признателен за любую помощь, которую я могу получить.

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

Итак, я не знаю, что это за ошибки, пока вы не опубликуете их, но у меня есть идея, почему ваш вывод преждевременно обрезается.

Итак, подведем итоги, давайте еще раз посмотрим на ваш код (соответствующая часть ":

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.

Цикл больше не будет выполняться, потому что мы преждевременно прервали его , вернув его, только выведя первую строкуматрица.

Решение: Просто переместите оператор возврата за пределы цикла следующим образом:

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;

И это должно решить проблему.

Наконец, несколько дружеских советов, примите совет Сами Кухмонена и сделайте отступ в своем коде.Это облегчает чтение и улавливание подобных вещей.

РЕДАКТИРОВАТЬ: Еще один момент, как упомянул Р.К.Лохана, вы, вероятно, тоже хотите извлечь эти строки из цикла:

    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;

Поскольку вы, вероятно, хотите делать их только один раз, а не несколько раз.

0 голосов
/ 26 февраля 2019

Вы допустили ошибку в последнем цикле 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 [] [] в качестве параметра функции, так как из-за ошибки многомерный массив должен иметь границы для всех измерений, кроме первого

Вы можете использовать двойной указатель для этой работы,Измените объявление функции check none на

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

, и код должен работать как символ.А также удалите эту строку, ее избыточность, так как имя_файла не используется.

string file_name = argv[1];
0 голосов
/ 26 февраля 2019

В комментарии вы спросили

У кого-нибудь есть лучший способ передать матрицу методу count_ones?

  1. Не делайтеt use

    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.

...