Если вы пытаетесь получить счет по порядку вместо счетчика в в алфавитном порядке , вам просто нужно согласовать индексы массива count
с порядкомсимволов в вашем входном буфере.Чтобы сделать это, просто зациклите все символы в вашем входном буфере и сделайте второй проход, подсчитав, сколько раз текущий символ встречается.Это даст вам порядковый счетчик количества повторений каждого символа, например,
#include <stdio.h>
#include <string.h>
#define COUNT 128
#define MAXC 1024
int main (void) {
char buf[MAXC] = ""; /* buffer to hold input */
int count[COUNT] = {0}; /* array holding inorder count */
fputs ("enter string: ", stdout); /* prompt for input */
if (!fgets (buf, MAXC, stdin)) { /* read line into buf & validate */
fputs ("error: EOF, no valid input.\n", stderr);
return 1;
}
/* loop over each character not '\n' */
for (int i = 0; buf[i] && buf[i] != '\n'; i++) {
char *p = buf; /* pointer to buf */
size_t off = 0; /* offset from start of buf */
while ((p = strchr (buf + off, buf[i]))) { /* find char buf[i] */
count[i]++; /* increment corresponding index in count */
off = p - buf + 1; /* offset is one past current char */
}
}
for (int i = 0; count[i]; i++) /* output inorder character count */
printf (i ? ", %c: %d" : "%c: %d", buf[i], count[i]);
putchar ('\n'); /* tidy up with new line */
return 0;
}
( примечание: strchr
используется для удобства, чтобы просто найти следующее вхождениетекущего символа в строке, а затем off
(смещение) используется для начала поиска со следующим символом, пока не найдены другие совпадения в строке. Вы можете просто использовать дополнительный цикл над символами в буфере, если выкак.)
Пример использования / Вывод
$ /bin/charcnt_inorder
enter string: hello
h: 1, e: 1, l: 2, l: 2, o: 1
Тем не менее, это пересчитывает каждый символ и дает счет снова, если символ дублируется (например, l: 2, l: 2
за каждый 'l'
).Теперь неясно из:
«мой вывод будет: h = 1, e = 1 l = 2
и т. Д.»
что вы намеревались в этом отношении, но с небольшим дополнительным усилиемВы можете использовать отдельный индекс и отдельный массив для хранения первого экземпляра каждого символа (скажем, массива chars[]
) вместе со счетчиком каждого в вашем массиве count[]
и сохранить количество внутренних символов, удаляя дубликаты символов.Необходимые изменения показаны ниже:
#include <stdio.h>
#include <string.h>
#define COUNT 128
#define MAXC 1024
int main (void) {
char buf[MAXC] = "",
chars[COUNT] = ""; /* array to hold inorder chars */
int count[COUNT] = {0};
size_t cdx = 0; /* add count index 'cdx' */
fputs ("enter string: ", stdout);
if (!fgets (buf, MAXC, stdin)) {
fputs ("error: EOF, no valid input.\n", stderr);
return 1;
}
for (int i = 0; buf[i] && buf[i] != '\n'; i++) {
char *p = buf;
size_t off = 0;
chars[cdx] = buf[i]; /* store in chars array */
if (i) { /* if past 1st char */
int n = i;
while (n--) /* simply check all before */
if (buf[n] == buf[i]) /* if matches current */
goto next; /* bail and get next char */
}
while ((p = strchr (buf + off, buf[i]))) {
count[cdx]++; /* increment count at index */
off = p - buf + 1;
}
cdx++; /* increment count index */
next:; /* goto label to jump to */
}
for (int i = 0; count[i]; i++)
printf (i ? ", %c: %d" : "%c: %d", chars[i], count[i]);
putchar ('\n');
return 0;
}
Пример использования / Вывод
$ /bin/charcnt_inorder2
enter string: hello
h: 1, e: 1, l: 2, o: 1
или
$ ./bin/charcnt_inorder2
enter string: amarillo
a: 2, m: 1, r: 1, i: 1, l: 2, o: 1
Теперь ваш 'l'
сообщается только один раз с правильным счетом.
Обратите внимание, что в каждом примере вы должны выполнять дополнительную проверку для обеспечения полного соответствия ввода в вашем буфере и т. д. ... Массив count
(и chars
)имели размер 128
, чтобы охватить весь диапазон значений ASCII.Не экономьте на размере буфера.Если вы явно ограничите свой ввод в верхнем или нижнем регистре - тогда вы можете ограничить размер счета до 26
, в противном случае вам нужно учитывать дополнительные символы и знаки препинания, которые будут встречаться.То же самое относится и к вашему входному буферу.Если вы ожидаете, что ваш максимальный вклад составит 500 символов, удвойте его (как правило, до следующей доступной степени два, нет реальных требований к степени двойки, но вы, вероятно, увидите это так).
Суть в том, что я предпочел бы быть на 10 000 символов длиннее, чем один символ слишком коротким ..., что приводит к неопределенному поведению .
И наконец, как упоминалось в моем комментарии никогда, никогда, никогда использовать gets
.Это настолько небезопасно, что было удалено из стандартной библиотеки C в C11.Вместо этого используйте fgets
или POSIX getline
.
Просмотрите все и дайте мне знать, если у вас есть дополнительные вопросы.