Почему первое значение моего массива char 10? - PullRequest
1 голос
/ 06 ноября 2019

Я новичок в программировании, но я хотел создать программу, которая получает в качестве входных данных число (длина), а затем сохраняет серии значений a и b указанной длины. Наконец, он должен вывести числа как числа ascii. (поэтому 97 и 98) Я подумал, что мне нужно распределить массив массивов длины по размеру, а затем выполнить цикл for и вывести все как целое число.

Однако проблема в том, что я получаю значение 10в качестве значения первой буквы. Большое спасибо за любую помощь!

int main()
{
    int length;
    scanf("%d", &length);
    char *matrix = malloc((length + 1 ) * sizeof(char));

    for (int i = 0; i < length; i++)
    {
            scanf("%c", &matrix[i]);
    }

    for (int i = 0; i < length; i++)
    {
            printf("\n%d", matrix[i]);
    }

    return 0;
}

При вводе 3 в первой строке и aba в следующей строке я получаю 10 97 98. Однако я ожидал, что это будет 97 98 97. Почему я получаюзначение 10 на первом месте массива?

Ответы [ 2 ]

2 голосов
/ 06 ноября 2019

Используйте

scanf(" %c", &matrix[i]);
      ^^^^

вместо

scanf("%c", &matrix[i]);
       ^^

Когда формат начинается с пробела, все пробелы пропускаются.

Из стандарта C (7.21. 6.2 Функция fscanf)

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

10 - это код ASCII символа новой строки '\n' (пробел), который присутствовал во входном буфере после ввода длины массива.

0 голосов
/ 06 ноября 2019

Первый scanf() со строкой формата %d оставляет новую строку во входном буфере.

Что здесь происходит, так это то, что ваш терминал собирает входные данные по одной полной строке за раз, передавая их программе, а затем scanf() считывает только цифры из буфера, оставляя там символ новой строки дляследующий scanf() чтобы увидеть. То же самое произойдет, если вы введете 10 abc: пробел, abc и символ новой строки останутся там.

Это несоответствие не является тем, чего обычно ожидают люди, и это одна из вещей, которая делает scanf() раздражает. Я бы предложил вместо этого использовать fgets(), чтобы сначала прочитать полную строку, совпадающую с тем, что дает терминал, а затем проанализировать число из него с помощью sscanf() или strtol() (или atoi()).

Thisустраняет проблему в точке, где читается первая строка, вместо передачи ее следующей функции ввода для обработки. В противном случае все ваши функции ввода связаны друг с другом, если следующий ввод будет для всей строки с возможным пробелом, вам нужно будет знать, ожидаете ли вы очистить ранее существовавший символ новой строки или нет. (Вы также можете заменить более поздние scanf("%c") на getchar(), но это не относится к буферизации.)

Тем не менее, цикл scanf("%c") / getchar() может по-прежнему видеть символы новой строки, если вы вводите строкикоторые не содержат столько символов, сколько ожидает цикл, поэтому, если вы вообще не хотите их видеть, отфильтруйте их.

Итак, что-то вроде этого:

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

int main(void)
{
    int length;
    char linebuf[100];
    fgets(linebuf, 100, stdin);
    length = strtol(linebuf, NULL, 10);
    char *matrix = malloc(length + 1);

    for (int i = 0; i < length; i++)
    {
        matrix[i] = getchar();
    }

    for (int i = 0; i < length; i++)
    {
        printf("\n%d", matrix[i]);
    }
    printf("\n");

    return 0;
}

(Очевидным недостатком fgets() является то, что вам нужно выбрать максимальную длину для входной строки, выделить буфер и вызвать другую функцию в дополнение к нему.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...