2D массив символов, печать лишних символов сверх лимита? - PullRequest
0 голосов
/ 15 февраля 2020

Вывод кода
Я хочу создать массив символов, в котором есть 'n' строк и каждая строка имеет символ. В данном коде я попросил пользователя ввести количество строк (n), затем я создаю переменную 'chr', и каждая строка содержит только один символ. Затем я спрашивал персонажей одного за другим и сохранял их в соответствующих строках, но когда я беру на печать эти символы, происходит нечто странное. В первой строке, в которой должен храниться только один собственный символ, хранятся все символы разных строк. Почему? Может кто-нибудь объяснить мне это?

#include <stdio.h>

int main(void) {
    int n;
    scanf("%d", &n);

    char chr[n][1];

    for (int i = 0; i < n; i++) {
        printf("Enter the %d character?\n", i);
        scanf("%s", chr[i]);
    }
    // printing
    for (int i = 0; i < n; i++) {
        printf("\n%s\n", chr[i]);
    }
    return 0;
}

Ответы [ 2 ]

3 голосов
/ 15 февраля 2020

В первой строке, в которой должен храниться только один собственный символ, хранятся все символы разных строк. Почему? Может ли кто-нибудь объяснить мне это?

scanf("%s", chr[i]);

%s читает всю строку, пока не встретит символ пробела, такой как символ новой строки \n, и записывает ее (исключая символ пробела) в первое измерение; не только один персонаж.

Вы также забыли, что, поскольку вы пытаетесь прочитать строку, \0 автоматически добавляется к каждой строке, но поскольку объявление chr, в измерении есть место только для одного символа, а не для двух. ,

Многомерный массив непрерывно размещается в памяти, что обеспечивает то, что символ \0 для строки в предыдущем измерении сохраняется в первом и единственном символе следующего измерения; в следующей итерации scanf затем перезаписывает этот символ \0 для хранения второго символа, но снова записывает \0 этой строки в первый единственный объект следующего измерения и так далее для каждой итерации, что заканчивается полным беспорядком неопределенного поведения, плюс \0 последней строки записывается за пределы полного многомерного массива.

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

Для получения дополнительной информации о неопределенном поведении посмотрите на этот вопрос:

Не определено, не определено и реализация -определенное поведение


Скорее используйте

scanf(" %c", &chr[i][0]);

со спецификатором формата %c для чтения только одного символа за итерацию и реализации символа пробела перед %c спецификатор формата для перехвата новой строки \n, оставленной в stdin по потреблению scanf предыдущего прохождения l oop или любой начальный пробел.


Также замените:

  for(int i = 0; i<n; i++) {
    printf("\n%s\n", chr[i]);

на

  for(int i = 0; i<n; i++) {
    printf("\n %c \n", chr[i][0]);

Весь код будет тогда:

#include <stdio.h>

int main(void) {

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

  char chr[n][1];

  for(int i = 0; i<n; i++) {
    printf("Enter the %d character?\n", i);
    scanf(" %c", &chr[i][0]);
  }
  // printing
  for(int i = 0; i<n; i++) {
    printf("\n %c \n", chr[i][0]);
  }
return 0;
}
0 голосов
/ 15 февраля 2020

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

, поэтому в памяти это

char array[3][1] = {{'a'},{'b'}{'c'}};

выглядит так:

char array[3] ={'a','b','c'};

или

char array[3] = {"abc"};

переменная массива является указателем по адресу в памяти, где расположен первый символ, если вы используете [], вы просто переходите размер байта (символа) к следующему символу,

с двумерным массивом, это похоже, 1-я скобка делает Вы перепрыгиваете sizeof (2darray [0]) байтов, который в этом случае совпадает с sizeof (char), поскольку длина равна 1

...