Я работаю над программой для курса, где программе нужно прочитать одну строку пользовательского ввода и подсчитать, сколько каждой буквы находится в строке. количество каждой буквы помещается в массив. Например, если пользователь вводит «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'), а затем прочитает следующий символ слова. Он должен заканчиваться чтением пользовательского ввода на новой строке. На самом деле программа просто записывает первый символ и затем завершает работу.
Вы, вероятно, хотите while(userChar != '\n')
вместо ==
.
Есть две проблемы с вашим кодом.
Сначала scanf("%c ", &userChar);
будет читать один символ а также, а затем пропустит любое количество следующих за ним пробелов. (Подробнее см. этот ответ.) Под пробельные символы обычно подразумевается ' ', '\t', '\r', '\n', '\v', '\f'. Таким образом, ваш userChar
будет содержать никогда символ новой строки в вашем коде.
Во-вторых, ваше условие do-while неверно. Вы заставляете его работать, «пока 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');
Ваша проблема
while(userChar == '\n');
Когда вы читаете 'A'
в "Apple"
, userChar
не == '\n'
приводит к завершению вашего oop после первой итерации. То, что вы намеревались, было:
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
Просмотрите все и дайте мне знать, если у вас есть дополнительные вопросы.
Используйте
fgetc
вместоfscanf