After Accept Answer
A method that meets these specs: (IMO, the other answers do not meet all)
It is practical/efficient when char
has a wide range. Example: CHAR_BIT
is 16
or 32
, so no use of bool Used[1 << CHAR_BIT];
Works for very long strings (use size_t
rather than int
).
Does not rely on ASCII. ( Use Upper[]
)
Defined behavior when a char
< 0. is...()
functions are defined for EOF
and unsigned char
static const char Upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static const char Lower[] = "abcdefghijklmnopqrstuvwxyz";
void LetterOccurrences(size_t *Count, const char *s) {
memset(Count, 0, sizeof *Count * 26);
while (*s) {
unsigned char ch = *s;
if (isalpha(ch)) {
const char *caseset = Upper;
char *p = strchr(caseset, ch);
if (p == NULL) {
caseset = Lower;
p = strchr(caseset, ch);
}
if (p != NULL) {
Count[p - caseset]++;
}
}
}
}
// sample usage
char *s = foo();
size_t Count[26];
LetterOccurrences(Count, s);
for (int i=0; i<26; i++)
printf("%c : %zu\n", Upper[i], Count[i]);
}