TESTJ
TESTJ

Reputation: 3

Reading lines ahead in a file (In C)

I have a file that looks like this:

This is the first line in the file

This is the third line in the file

Where I have a blank line in the file (On line 2). I want to read the file line by line (Which I do using fgets), but then i want to read ahead just check if a line there is a blank line in the file.

However, My while fgetshas a break statement in it, because my function is only so posed to read the file a line at a time per function call.

so if I call the function:

func(file);

It would read the first line, then break.

If I called it again, it would read the second line then break, etc.

Because I have to implement it this way, it's hard to read ahead, is there any way I can accomplish this?

This is my code:

int main(void) {
    FILE * file;

    if(file == NULL){perror("test.txt"); return EXIT_FAILURE;} 

    readALine(file);

}

void readALine(FILE * file) {

    char buffer[1000];

    while(fgets(buffer,sizeof(buffer),file) != NULL) {
        //Read lines ahead to check if there is a line
        //which is blank

        break; //only read a line each FUNCTION CALL
    }


}

So to clarify, if I WAS reading the entire file at once (Only one function call) it would go like this (Which is easy to implement).

int main(void) {
        FILE * file = fopen("test.txt","r");

        if(file == NULL){perror("test.txt"); return EXIT_FAILURE;}

        readALine(file);

    }

void readALine(FILE * file) {

    char buffer[1000];

    while(fgets(buffer,sizeof(buffer),file) != NULL) {

        if(isspace(buffer[0]) {
            printf("Blank line found\n");
        }
    }


}

But since I'm reading the file in (Line by line, per function call), The second piece of code above wouldn’t work (Since I break per line read, which I can't change).

Is there a way I could use fseek to accomplish this?

Upvotes: 0

Views: 546

Answers (3)

cewbost
cewbost

Reputation: 11

A while loop ending in an unconditional break is an if statement, so I don't really see why you are using a while loop. I'm also assuming you are not worried about a single line being longer than 1000 chars.

the continue statement jumps over to the next iteration of the loop and checks the condition again.

void readALine(FILE * file) {

    char buffer[1000];

    while(fgets(buffer,sizeof(buffer),file) != NULL) {

        if(!isspace(buffer[0]) { //note the not operator
            //I'm guessing isspace checks for a newline character since otherwise this will be true also for lines beginning with space
            continue; //run the same loop again
        }
        break;
    }

    //buffer contains the next line except for empty ones here...


}

Upvotes: 1

Willis Blackburn
Willis Blackburn

Reputation: 8204

The while loop in readALine reads lines until the end of the file. So it will skip blank lines, and all other lines.

You can return from within the loop if you've found a non-blank line:

while(fgets(buffer,sizeof(buffer),file) != NULL) {
    if (buffer[0] != '\n')
        return;
}

If you also want to skip lines that consist of nothing but spaces, you can write a function that does that check:

bool isNothingButWhitespace(char *s) {
    while (*s == ' ' || *s == '\n')
        s++;
    return *s == '\0';
}

This will find the first character that's not whitespace. If it's the string terminator '\0' then it will return true (the string was nothing but whitespace) otherwise falseS (there was some non-whitespace character found).

If the while loop in readALine completes due to it reaching the end of file, you need some way to signal that back to the caller. I recommend setting buffer[0] = '\0'.

Upvotes: 0

haltode
haltode

Reputation: 618

You can "read ahead" by simply storing your position in the file (with position = ftell(your_file)), then read the line, if this is a blank line do whatever you have to do, and finally go back to the position you were (with fseek(your_file, position, SEEK_SET)).

Hope this helps !

Upvotes: 0

Related Questions