Pink Panda
Pink Panda

Reputation: 59

Why my inner loop only run once?

a.c

#include <stdio.h>

int main(int argc, char *argv[])
{

    int i, counter=0;
    char c;

    FILE *file=fopen("a.txt","r");

    for (i = 0x41 ; i < 0x45; i++)
    {
        printf("%c(%x) ",i ,i);
        while ((c = fgetc(file)) != EOF)
        {
            if (i == (char) c)
                counter++;
        }
        printf("%d\n", counter);
        counter=0;
    }
    fclose(file);
    return 0;
}

a.txt

AAABBBAAA

I don't understand why the for loop runs perfectly but the while loop only runs once.

The output looks like

enter image description here

Upvotes: 5

Views: 171

Answers (3)

Sourav Ghosh
Sourav Ghosh

Reputation: 134326

Read the man page for fgetc(), (emphasis mine)

fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error.

So, once the while loop has run, it will exit once fgetc() returns EOF and it will keep returning EOF for all successive calls.

You need to reset the file pointer to the beginning of the stream (using rewind() or fseek()) to start over from the beginning.

That said,

  • fgetc() returns an int and a char is too short to store all the possible return value (for example, EOF itself). Change the type of c to int.
  • For a hosted environment, int main() should at least be int main(void) to conform to the standard.

Upvotes: 7

iqstatic
iqstatic

Reputation: 2382

This should do the job for you:

#include <stdio.h>

int main(void)
{

    int i, counter=0;
    int c;

    FILE *file=fopen("a.txt","r");

    for (i = 0x41 ; i < 0x45; i++)
    {
        printf("%c(%x) ",i ,i);
        while ((c = fgetc(file)) != EOF)
        {
            if (i == c) counter++;
        }
        rewind(file);
        printf("%d\n", counter);
        counter=0;
    }
    fclose(file);
    return 0;
}

Upvotes: 3

user1919238
user1919238

Reputation:

In the first run of the for loop, the whole file gets used up, and you never reset it. So it will only successfully search for character 0x41.

You need to do one of these two operations after the while loop:

fseek(file, 0, SEEK_SET);

rewind(file);

The first is preferred because of better error handling.

Upvotes: 3

Related Questions