Why my inner loop only run once?
Asked Answered
S

3

5

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

Shiekh answered 4/11, 2016 at 7:54 Comment(6)
maybe you need to rewind?Inequitable
How did you determine that the while loop ran only once?Davedaveda
@DavidSchwartz probably by seeing the counter value. (I posted and deleted the same comment a while ago.) :)Inequitable
Because after you read the file once you're now at the end of the file?Shellback
rewind(file) after while loop will do the jobQuinquennium
ideone.com/A5e5zkXanthe
I
7

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.
Inequitable answered 4/11, 2016 at 7:58 Comment(1)
You're welcome. You can also consider accepting an answer that helped you.Inequitable
C
3

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.

Coracorabel answered 4/11, 2016 at 7:58 Comment(0)
O
3

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;
}
Orlan answered 4/11, 2016 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.