Странная проблема - размерный массив ввода в c - PullRequest
1 голос
/ 09 января 2020

Я написал программу для проверки того, является ли квадрат n*n матрица «идеальной», то есть каждая строка и строка содержат ровно один экземпляр каждого числа от 1 до n.

Я также написал Основная функция для выделения памяти для заданного размера и получения значений этой матрицы от пользователя.

Кажется, что это работает нормально, за исключением случаев, когда я выбрал 4 для размера и введите эту матрицу: {{1,2,3,4},{2,1,4,3},{3,4,2,1),{4,3,1,2}}.

Я получаю матрицу {{1,2,3,4},{2,**3**,4,3},{3,4,**3**,1},{4,3,1,2}}.

Это похоже на входные данные, но я могу t find what неправильно: (

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int IsPerfect(int *arr, int size);

void main() {
    int size = 0, i = 0, j = 0, vol = 0;
    printf("please enter matrix size, 0 to exit:\n");
    scanf("%d", &size);
    printf("size is :%d\n", size);
    while (size != 0) {  //loop for allocating and inputing ,matrix
        int *pmatrix = (int *)malloc(size*size * sizeof(int));
        printf("please input matrix:\n");
        for (i = 0; i < size; i++)
            for (j = 0; j < size; j++) {
                printf("[%d][%d]\n", i, j);
                scanf("%d", ((pmatrix + i) + j));  //storing matrix values
            }
        for (i = 0; i < size; i++) {
            for (j = 0; j < size; j++)
                printf("[%d]", *((pmatrix + i) + j));  //printing matrix
            printf("\n");
        }
        IsPerfect(pmatrix, size);  //perfect check
        free(pmatrix);
        printf("please enter matrix size, 0 to exit:\n");
        scanf("%d", &size);
    }
    printf("bye bye!\n");
}

int IsPerfect(int *arr, int size) {
    int i = 0, j = 0, w = 0, perf = 1;
    int *check = (int *)malloc(sizeof(int) * size);

    for (w = 0; w < size; w++) {  //horizontal check
        for (i = 0; i < size; i++)
            *(check + i) = 0;
        for (i = 0; i < size; i++)
            for (j = 1; j <= size; j++)
                if (*((arr + w) + i) == j)
                    *(check + j - 1) = *(check + j - 1) + 1;
        for (i = 0; i < size; i++)
            if (*(check + i) == 0 || *(check + i) > 1)
                perf = 0;
    }
    for (w = 0; w < size; w++) {  //vertical check
        for (i = 0; i < size; i++)
            *(check + i) = 0;
        for (i = 0; i < size; i++)
            for (j = 1; j <= size; j++)
                if (*((arr + i) + w) == j)
                    *(check + j - 1) = *(check + j - 1) + 1;
        for (i = 0; i < size; i++)
            if (*(check + i) == 0 || *(check + i) > 1)
                perf = 0;
    }


    if (perf == 1)
        printf("the matrix is perfect\n");
    if (perf == 0)
        printf("the matrix is not perfect\n");
    free(check);
    return perf;
}

1 Ответ

0 голосов
/ 10 января 2020

следующий предложенный код:

  1. аккуратно компилируется
  2. использует соответствующий горизонтальный и вертикальный интервал для удобства чтения
  3. правильно проверяет (и обрабатывает) ошибки
  4. использует size_t для типов индексов, так как эти значения никогда не должны быть меньше 0 и лучше соответствуют ожиданиям malloc() функции
  5. использует операторы типа: for ( size_t col = 1; col <= size; col++ ) для ограничения scope локальных переменных для включающего for() l oop тела
  6. исправляет проблему с входной последовательностью, где метод доступа к элементам матрицы был неправильным
  7. НЕ исправляет проблему внутри функции check(), где, опять же, метод доступа к матричным элементам неверен
  8. проблема в функции check() заключается в адресации элементов массива
  9. Переименованные переменные i и j для лучшего понимания. i ==> row и j ==> col

Примечание: это утверждение типично для проблем в коде:

if ( *(check + row) == 0 || *(check + row) > 1 )

, поскольку check находится в [0] [0] поэтому при добавлении row, который индексируется по первой строке IE [0] [0] ... [0] [3]. Не то, что код должен сделать, чтобы проверить столбец матрицы

Возможно, вы имели в виду:

if ( *(check + size*row + col) == 0 || *(check + size*row + col) > 1 )

, который будет индексировать [0] [col] ... [3] [col ]

А теперь предложенный код:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


int IsPerfect( int *arr, size_t size );

int main( void ) 
{
    size_t size;

    printf("please enter matrix size, 0 to exit:\n");
    scanf("%zu", &size);
    printf("size is :%zu\n", size);

    while ( size != 0 ) 
    {  //loop for allocating and inputing ,matrix
        int *pmatrix = malloc( size*size * sizeof(int) );
        if( ! pmatrix )
        {
            perror( "malloc failed" );
            exit( EXIT_FAILURE );
        }

        printf( "please input matrix:\n" );

        for ( size_t row = 0; row < size; row++)
        {
            for ( size_t col = 0; col < size; col++) 
            {
                printf( "[%zu][%zu]\n", row, col );
                if( scanf( "%d", &pmatrix[ (size*row) + col ]) != 1 )  //storing matrix values row by row
                {
                    fprintf( stderr, "scanf for matrix entry failed\n" );
                    free( pmatrix );
                    exit( EXIT_FAILURE );
                }
            }
        }

        for ( size_t row = 0; row < size; row++) 
        {
            for ( size_t col = 0; col < size; col++)
            {
                printf( "[%d]", pmatrix[ row*size + col ] );  //printing matrix
            }
            printf( "\n" );
        }

        IsPerfect( pmatrix, size );  //perfect check
        free( pmatrix );

        printf( "please enter matrix size, 0 to exit:\n" );
        scanf( "%zu", &size );
    }
    printf( "bye bye!\n" );
}


int IsPerfect( int *arr, size_t size ) 
{
    int  perf = 1;

    int *check = malloc( sizeof(int) * size );
    if( !check )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    for ( size_t w = 0; w < size; w++ ) 
    {  //horizontal check
        for ( size_t row = 0; row < size; row++ )
        {
            *(check + row) = 0;
        }

        for ( size_t row = 0; row < size; row++ )
        {
            for ( size_t col = 1; col <= size; col++ )
            {
                if ( *((arr + w) + row) == (int)col )
                {
                    *(check + col - 1) = *(check + col - 1) + 1;
                }
            }
        }

        for ( size_t row = 0; row < size; row++ )
        {
            if ( *(check + size*row) == 0 || *(check + size*row) > 1 )
            {
                perf = 0;
            }
        }
    }

    for ( size_t w = 0; w < size; w++ ) 
    {  //vertical check
        for ( size_t row = 0; row < size; row++ )
        {
            *(check + size*row) = 0;
        }

        for ( size_t w = 0; w < size; w++ )
        {
            for ( size_t col = 1; col <= size; col++ )
            {
                 // why expect a position reference in the matrix to be the same as the content
                if ( *((arr + size*col) + w) == (int)col )      
                {
                    *(check + col - 1) = *(check + col - 1) + 1; //  causes seg fault
                }
            }
        }

        for ( size_t row = 0; row < size; row++ )
        {
            if ( *(check + row) == 0 || *(check + row) > 1 )
            {
                perf = 0;
            }
        }
    }


    if (perf == 1)
    {
        printf( "the matrix is perfect\n" );
    }

    else
    {
        printf( "the matrix is not perfect\n" );
    }

    free( check );
    return perf;
}

Примечание: выполнение предложенного кода и использование данных OP приводит к:

[1][2][3][4]
[2][1][4][3]
[3][4][2][1]
[4][3][1][2]

, так теперь операция ввода правильная, но функция check() все еще не активна (что приводит к событию сбоя сегмента на (приблизительной) строке 109:

if ( *((arr + size*col) + w) == (int)col ) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...