0

this program will keep reading next 20 lines until user enters 'q' or file reading is finished.

now for file reading is finished part, I've condition on line 29 of this program flag != NULL

as per my understanding fgets() returns NULL after it reach EOF but this condition doesn't work. what can I do to stop the loop after file has been read?

I'm using this file for testing and here's my program:

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main()
{
    char name[66];
    printf("Enter name of  file: ");
    scanf("%65s", name);

    FILE *fp = fopen(name, "r");

    if (!fp) {
        printf("can't open file for reading\n");
        return 1;
    }
    int  i = 1;

    char buffer1[1000];
    char *flag;
    char c;

    do {
        do {
            i++;
            flag = fgets(buffer1, 999, fp);
            printf("%s", buffer1);
            //printf("%d***\n", i);  //debug - print line number
        } while (i % 20 != 0 && flag != NULL);
        scanf(" %c", &c);
    } while (c != 'q');

    return 0;
}
3
  • isn't scanf blocking... meaning it will actually pause each 20 until the user reacts Commented Jan 11, 2017 at 11:24
  • Yes, that's what I want. scanf will ask user input after each 20 lines. Commented Jan 11, 2017 at 11:32
  • Sidenote: flags are typically boolean values, not pointers. Using moire appropriate names makes code much more clear and help spotting logical errors. Commented Jan 11, 2017 at 12:29

2 Answers 2

3

Your outer do-while loop won't terminate until the user enters q even when EOF is reached.

do {
    do {
        i++;
        flag = fgets(buffer1, 999, fp);
        printf("%s", buffer1);
        //printf("%d***\n", i);  //debug - print line number
    } while (i % 20 != 0 && flag != NULL);
    scanf(" %c", &c);
} while (c != 'q'); // no EOF checking here

This will probably do what you want:

do {
    do {
        i++;
        flag = fgets(buffer1, 999, fp);
        // only print if fgets() returned new data
        if (flag != NULL) {
            printf("%s", buffer1);
        }
        //printf("%d***\n", i);  //debug - print line number
    } while (i % 20 != 0 && flag != NULL);
    scanf(" %c", &c);
} while (c != 'q' && flag != NULL);
Sign up to request clarification or add additional context in comments.

4 Comments

gist.github.com/ganganimaulik/951ec5cbf0fb109b06de893d5742ee3a I've done this and it solves the issue but last line gets printed twice :o
@MaulikGangani last line gets printed twice That's because you call printf() even if your call to fgets() fails and returns NULL. See my edit
Note: 1000-1 not needed in char buffer1[1000]; ... fgets(buffer1, 999, fp); Better to use 1000 via fgets(buffer1, sizeof buffer, fp);.
@chux Those would be improvements, but I decided to not make such changes and just make changes relevant to the question. I also considered the additional parenthesis used in the other answer, but again, I tried to stay close to the original posted code. (I became a big fan of parenthesizing everything when I spent close to a week trying to run down a bug that I finally traced to a huge conditional clause that omitted such parenthesis...)
2

You are not exiting the outer loop. In the outer while loop change

while (c != 'q');

to

while ((c != 'q') && (flag !=NULL));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.