Копирование ввода из `getchar ()` в другую переменную - PullRequest
3 голосов
/ 05 апреля 2020

В следующем примере кода из книги K & R, если я заменю putchar(c) на printf("%c", c), код работает так же. Но если я заменю его на printf("%d", c), то получится выходной сигнал гибрини sh.

#include <stdio.h>
int main() {
  int c;
  c = getchar();
  while (c != EOF) {
    putchar(c);
    c = getchar();
  }
}

Начиная с здесь , я узнал, что getchar() преобразует стандартный ввод в 8-битный символ, значение которого находится в диапазоне от 0 до 255.

Теперь я хочу напечатать значение c, используя putchar(c) в одной строке и printf("%d", c) в другой строке. Поэтому я написал следующий код:

#include <stdio.h>

int main() {
  int c, b;

  c = getchar();
  b = c;
  while (c != EOF && c != 10) {
    printf("%c",c);
    c = getchar();
  }
  printf("\n");
  while (b != EOF && b != 10) {
    printf("%d\t",b);
    b = getchar();
  }
}

Я использовал условие c != 10, поскольку символ новой строки читается как 10 по getchar(). Я ожидал, что код будет работать как

$ ./a.out
783
783
55 56 51

, но программа завершится как

$ ./a.out
783
783
55

Я понимаю, что getchar() принимает входные данные из stdin, а переменная b не является stdin. Так как мне скопировать переменную c в b, чтобы моя программа работала так, как я ожидал?

Ответы [ 3 ]

2 голосов
/ 05 апреля 2020

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

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

Допустим, вы берете ввод, который может содержать не более 100 символов.

#include <stdio.h>

int main(void) {
    char c[100]; // A char array
    fgets(c,100,stdin);
    int x=0;
    while (c[x] != 10 && c[x] != EOF)
        printf("%c",c[x++]);
    printf("\n");
    x = 0;
    while (c[x] != 10 && c[x] != EOF) // You can simply compare it with the newline character too.
        printf("%d ",c[x++]);
    printf("\n");
    return 0;
}

Есть много способов сделать это. Вы также можете прочитать stdin символьно-символьно и сохранить его в массиве. Однако, поскольку вам необходимо отображать значения ASCII символов в другой строке после отображения самих символов, вам придется сохранять их в массиве.

2 голосов
/ 05 апреля 2020

Проблема в том, что ваш код не «запоминает» входные данные, которые вы дали в первом l oop (и не может в его нынешнем виде). Итак, после того, как вы закончили это l oop, ваш второй l oop хочет прочитать символы для b (после того, как он выведет первое значение, которое запоминается из предыдущей строки b = c).

Итак, после вывода 55 (целое число значение символа 7) он ожидает дальнейшего ввода.

Вероятно, самый простой способ получить выход, который вы ищете, должен иметь массив входных символов. Затем вы можете вывести значения %c по мере их чтения (как и раньше), а затем повторно запустить выходные данные в формате %d в следующем for l oop.

Здесь демонстрация, которая, как я думаю, вам нужна:

#include <stdio.h>
#define MAXINS 20 // Set to the maximum number of input characters you want to allow
int main()
{
    int c[MAXINS];
    int i = 0, n = 0;
    c[0] = getchar();
    while (i < MAXINS && c[i] != EOF && c[i] != 10) {
        printf("%c", c[i]);
        c[++i] = getchar();
        ++n;
    }
    printf("\n");
    for (i = 0; i < n; ++i) {
        printf("%d\t", (int)(c[i]));
    }
    return 0;
}

Не стесняйтесь просить дальнейших разъяснений и / или объяснений.

РЕДАКТИРОВАТЬ : по делу в вашем первом абзаце, «Но если я заменю его на printf («% d », c), это даст вывод gibberi sh.» Хорошо, когда я попробую следующий код и дам 783 и затем нажимаю return (который генерирует новую строку), я получаю ожидаемое 55565110 в качестве вывода:

int main()
{
    int c;
    c = getchar();
    while (c != EOF) {
        printf("%d", c);
        c = getchar();
    }
    return 0;
}

Это может выглядеть как gibberi sh, но это точно такой же вывод, как и вы ' ожидайте 'в вашем последующем коде, но без пробелов и с добавлением 10 для новой строки.

1 голос
/ 05 апреля 2020

Вы копируете только первый вход, чтобы скопировать всю строку, вам нужно сохранить каждый вход в буфер и проверить, не переполняет ли строка этот буфер на каждой итерации:

int main(void)
{
    enum {size = 256};
    char buffer[size];
    size_t count = 0;
    int c;

    while ((c = getchar()) && (c != '\n') && (c != EOF))
    {
        printf("%c", c);
        if (count < size)
        {
            buffer[count++] = (char)c;
        }
    }
    printf("\n");
    for (size_t iter = 0; iter < count; iter++)
    {
        printf("%d\t", buffer[iter]);
    }
    printf("\n");
}

Если Вы не хотите ограничивать буфер произвольным размером, тогда вам нужно изменить свой подход, чтобы использовать динамическую c память (realloc или связанный список)

...