The user enters a string of characters, but before that he enter the size of the string. Then I have to read and count how many times each letter is entered.
Here is my code:
#include <stdio.h>
char ab[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; //Size = 26
int main(void)
{
int i, j, size, counter[26];
char temp;
for(i=0; i<26; i++)
{
counter[i]=0;
}
scanf("%d",&size);
for(i=0; i<size; i++)
{
scanf("%c",&temp);
for(j=0; j<26; j++)
{
if(ab[j]==temp)
{
counter[j]++;
break;
}
}
}
for(i=0; i<26; i++)
{
printf("We have %d %c\n",counter[i],ab[i]);
}
return 0;
}
And here is my problem:
In the given code the for loop that reads executes one last time. So for example if you enter 7 it will execute 6 times instead of 7 even if it starts from 0. Do you know what the problem is?
for(i=0; i<size; i++){
will loop 7 times when size
is 7.
Your problem is as follows:
You enter a number for
scanf("%d",&size);
and press Enter. The above scanf
scans the number and leaves the newline character('\n'
) in the standard input stream. In the first iteration of the first loop,
scanf("%c",&temp);
sees the newline character and consumes it thus, making you think that the loop executes 1 less time. You can verify this by adding
printf("Got '%c'", temp);
after the scanf
in the loop.
Fix it by using
scanf(" %c",&temp);
The space before %c
discards all whitespace characters including none until the first non-whitespace character.
The problem is that %c
does not skip white space as do the numerical formats such as %f
and %d
.
The following scanf
can be used to skip white space and then read the next, non-white character.
scanf("%*[ \n\t]%c",&temp);
The *
says throw away what is read, don't store it in an output variable. The [...]
says read any sequence of characters matching the characters between the brackets, in this case, space, newline or tab.
Change your code to
#include <stdio.h>
int main(void) {
char ab[] = "abcdefghijklmnopqrstuvwxyz", temp;
int i, j, size, counter[26] = {0};
scanf("%d", &size);
for (i = 0; i <= size; ++i) { // One more iteration for the loop
scanf("%c", &temp);
for (j = 0; j < 26; ++j) {
if (ab[j] == temp) {
counter[j]++;
break;
}
}
}
for (i = 0; i < 26; ++i)
printf("We have %d %c\n", counter[i], ab[i]);
return 0;
}
However, prefer reading the string at once instead reading character by character
char str[size + 1];
scanf("%s", str);