Неправильное сохранение кода выходного массива символов, даже если код правильный - PullRequest
1 голос
/ 21 марта 2020

Код предназначен для линейного хранения строк и столбцов матрицы в другом массиве.

Пример: Для данной матрицы:

ab c d

efgh

ijkl

mnop

Задача - сохранить значения в новой матрице:

Матрица H содержит:

ab c d

efgh

ijkl

mnop

Матрица V содержит:

aeim

bfjn

c gko

dhlp

Код, который я написал:

#include<stdio.h>

int main() {
  int m, n;
  char a[10][10];

  scanf("%d%d", &m, &n);

  char horizontal[m][10], vertical[n][10];
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      scanf(" %c", &a[i][j]);
    }
  }

  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      horizontal[i][j] = a[i][j];
      vertical[i][j] = a[j][i];
    }

  }
  printf("horizontal values are:\n");
  for (int i = 0; i < m; i++) {
    printf("%s\n", horizontal[i]);
  }
  printf("vertical values are:\n");
  for (int i = 0; i < m; i++) {
    printf("%s\n", vertical[i]);
  }
}

Вывод, когда я выполняю этот код:

4
4
a b c d
e f g h
i j k l
m n o p

horizontal values are:
abcd
efgh
ijklñ²b
mnopb

vertical values are:
aeim
bfjn
cgko
dhlpb

Что не так в этом коде?

Ответы [ 2 ]

3 голосов
/ 21 марта 2020

У вас есть дополнительные символы, потому что когда вы обрабатываете строки символов как C строки, они должны заканчиваться нулем. Ваши массивы - это VLA, массивы переменной длины, которые нельзя инициализировать, когда они определены.

Есть несколько способов решить эту проблему.

(1) Не обрабатывать массив char как C строка и распечатать матрицу с двумя вложенными циклами. Скучно, но выполняет свою работу.

(2) Обнулить ваши массивы. Для этого вы должны выделить дополнительное место для каждой строки, куда вы положили '\0'. (Давайте также избавимся от 10 здесь. Вы знаете, насколько большими должны быть массивы, поэтому распределите их соответствующим образом.)

char horizontal[m][n + 1], vertical[n][m + 1];

Затем установите для последнего символа в каждой строке нулевой символ:

for (int i = 0; i < m; i++) horizontal[i][n] = '\0';
for (int i = 0; i < n; i++) vertical[i][m] = '\0';

(Weather Vane предложила инициализировать все массивы нулями, но, к сожалению, это работает только для массивов, размер которых известен во время компиляции. Однако ваши массивы имеют переменную длину. Вы можете использовать memset из <string.h> для обнуления массивов, если вы чувствуете себя комфортно с необработанными данными, и sizeof.)

(3) Используйте возможности строк формата printf: вы можете придать точности строку. Это число, которое означает «печатать как можно больше символов». Указав звездочку, вы можете прочитать это число из списка аргументов. Итак:

for (int i = 0; i < m; i++) {
    printf("%.*s\n", n, horizontal[i]);
    //       ^^      ^ precision
}

for (int i = 0; i < n; i++) {
    printf("%.*s\n", m, vertical[i]);
    //       ^^      ^ precision
}
1 голос
/ 21 марта 2020

вы вводите матрицу 4 и 4, но вы удалили двумерный массив из символов [m][10] и [n][10], когда вы используете %s, ваш printf будет для 10 символов, так как вы не не используйте \0 для завершения строки (вы напечатаете то, что было в буфере)

вы должны использовать \0 или печатать так же, как вы сканируете с помощью %c

int main()
{
    int m, n;
    char a[10][10];

    scanf("%d%d", &m, &n);

    char horizontal[m][10], vertical[n][10];
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            scanf(" %c", &a[i][j]);
        }
    }

    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            horizontal[i][j] = a[i][j];
            vertical[i][j] = a[j][i];
        }

    }
    printf("horizontal values are:\n");
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        printf("%c", horizontal[i][j]);
        printf("\n");
    }
    printf("vertical values are:\n");
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        printf("%c", vertical[i][j]);
        printf("\n");
    }
}

...