Search code examples
cloopsfileinfinite-loop

Why do i end up in an infinite loop when i read a file?


I'm trying my hardest to make this work but it just seems lite it doesn't want to.

The premise is simple. i'm trying to use fgetc to read a file and write the result in an array, stopping at any \n or EOF. It reads the line as intended but, for no apparent reason, as soon as the line ends, the program gets caught in an infinite loop. i tried using fgets, getline and even fscanf (i know it's not a good idea, but that was really my last one)

This is my fgetc attempt:

short ended = 0;
FILE *bRead = fopen(fdirs,"r");
char *dirscan[1024];
char scan;
short endln = 0;
while(ended==0) {
    for(int i=0;endln==0 && i<1024;i++) {
        if(i==1023) {
            dirscan[i]='\0';
            endln=1;
        }   else {
            scan = fgetc(bRead);
            if(scan == '\n' || scan == EOF) {
                dirscan[i]='\0';
                endln=1;
            } else {
                dirscan[i]=scan;
            }
        }
        printf("i= %d, s = %s\n",i,dirscan);
    }
    if(scan==EOF)
        ended=1;
}
fclose(bRead);

i even tried to delete the "if(scan==EOF)" but the program, looks like it never actually left the for loop while at the same time not even running the printf again and again

the file it reads (Edit:is created just before running this code and) looks like this:

0: .
0: .

and the printf writes this on the terminal:

i= 0, s = 0
i= 1, s = 0:
i= 2, s = 0: 
i= 3, s = 0: .
i= 4, s = 0: .

and neither keeps writing nor gives the terminal control afterwards

before you ask, yes i have other code under this one but i tested that one hundreds of time and it has no issues


Solution

  • You have a few problems here.

    The fgetc function returns an int, not a char. The reason for this is that EOF is typically -1, which falls outside the range of a unsigned char which is returned after casting to an int in the normal case.

    Change scan to an int to fix this.

    int scan;
    

    You also declared dirscan incorrectly:

    char *dirscan[1024];
    

    This creates an array of pointers, not an array of characters. You instead want:

    char dirscan[1024];
    

    Then the reason for the infinite loop. You never reset endln after you leave the for loop. This means that on later iterations of the while loop you never enter the for loop. So scan never changes, which means ended never changes.

    Set endln to 0 before entering the for loop:

    endln = 0;
    for(int i=0;endln==0 && i<1024;i++) {
    

    Finally, when you print dirscan at the end of the for loop, you don't have a null terminated string so you risk reading past the end of the array.

    Either move this printf to the outside of the loop or just print one character at a time in the loop.