For loop scans one less time in c

2019-07-13 02:11发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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);