Как прочитать пользовательский ввод с несколькими символами через scanf без использования строк - PullRequest
1 голос
/ 10 апреля 2019

Я работаю над программой для курса, где программе необходимо прочитать одну строку ввода пользователя и посчитать, сколько каждой буквы находится в строке.количество каждой буквы помещается в массив.Например, если пользователь вводит «Apple», программа должна поместить 1 a, 2 ps, 1 l и 1 e в счетный массив.Моя проблема в том, что мой профессор говорит, что я не могу использовать строки в программе. Я не уверен, как хранить несколько символов, чтобы scanf мог их прочитать без использования строки.Когда он обратился за помощью, он сказал, что нужно читать ввод по одному символу за раз.

Я пытался использовать scanf в цикле do-while для чтения каждого символа ввода, но большинство моих попыток только что закончилосьтолько с первым прочитанным символом и помещенным в массив, который записывает количество букв.

printf("ENTER A LINE OF TEXT: \n");
  do {
  scanf("%c ", &userChar);      
  userChar = toupper(userChar);
  userCharVal = userChar;
  histo[userCharVal - 65] = histo[userCharVal - 65] + 1;
  } while(userChar == '\n');

если пользователь вводит «яблоко», соответствующий массив histo [] будет обновляться в зависимости от того, какая буква была набрана.т. е. если пользователь ввел яблоко, программа сначала добавит 1 к histo [0] (соответствует «a»), а затем прочитает следующий символ слова.Это должно закончить чтение ввода пользователя на новой строке.На самом деле, программа просто записывает первый символ, а затем заканчивается.

Ответы [ 2 ]

1 голос
/ 10 апреля 2019

Ваша проблема

while(userChar == '\n');

Когда вы читаете 'A' в "Apple", userChar не == '\n' не приводит к прекращению вашего действия после первой итерации. То, что вы намеревались было:

while(userChar != '\n');

( примечание "!=" вместо "==")

При этом ваш код должен работать, хотя нет необходимости использовать отдельные userChar и userCharVal.

Чтобы немного разобраться, просто используйте один int, чтобы прочитать символ с getchar(), нет необходимости в scanf (и его лучше избегать). Требуется дополнительная проверка того, что символ равен [a-zA-Z], чтобы убедиться, что вы увеличиваете допустимый индекс на histo[userCharVal - 65]. (и не используйте цифры типа 65, когда вы можете использовать 'A', чтобы четко указать, что вы делаете)

В целом, вы можете сделать что-то похожее на:

#include <stdio.h>
#include <ctype.h>

#define NCHR   26   /* to cover each character in the alphabet */

int main (void) {

    int frequency[NCHR] = {0},  /* frequency of each char initialized to zero */
        c;                      /* character returned by getchar() */

    fputs ("enter a line of text: ", stdout);
    while ((c = getchar()) != '\n' && c != EOF) /* read each char */
        if (isalpha(c))                         /* validate a-zA-Z */
            frequency[toupper(c) - 'A']++;      /* increment element */

    puts ("\nfrequency of characters:\n");
    for (c = 0; c < NCHR; c++)
        if (frequency[c])   /* output lowercase per your example */
            printf (" %c : %d\n", c + 'a', frequency[c]);
}

( примечание: также требуется дополнительная проверка против EOF. Нет гарантии на '\n' Пользователь может сгенерировать руководство EOF с помощью Ctrl + d в Linux или Ctrl + z в Windows, чтобы обозначить конец ввода или полностью отменить ввод)

Пример использования / Вывод

$ ./bin/charfreqarray
enter a line of text: Apple

frequency of characters:

 a : 1
 e : 1
 l : 1
 p : 2

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

1 голос
/ 10 апреля 2019

У вашего кода две проблемы.

Сначала scanf("%c ", &userChar); прочитает один символ и , а затем пропустит любое количество следующих пробельных символов.(См. этот ответ для более подробной информации). пробелами , это обычно означает '', '\ t', '\ r', '\ n', '\ v', '\ F».Таким образом, ваш userChar будет никогда содержать символ новой строки в вашем коде.

Во-вторых, ваше условие выполнения задано неверно.Вы заставляете его работать «пока userChar равен символу новой строки», что всегда ложно, поэтому цикл никогда не будет выполняться более одного раза.Требуемое условие userChar != '\n'.

Итак, попробуйте следующее:

    printf("ENTER A LINE OF TEXT: \n");
    do
    {
        scanf("%c ", &userChar);
        userChar = toupper(userChar);
        userCharVal = userChar;
        histo[userCharVal - 65] = histo[userCharVal - 65] + 1;
    } while (userChar != '\n');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...