C program to count number of lines in a file
As you say, it works fine.  But I can nitpick.

The main flaw is that you could get a wrong count if any line is longer than 999 bytes.  (In general, you should stress-test your code by cranking down the buffer size to ridiculously small numbers and checking whether you obtain the same results.)

The performance could be improved.  Since fgets() has no way of knowing in advance where the newlines occur, it must read the file contents into a temporary buffer (which is invisible to you), then copy each line into the line buffer.  Since only care about counting '\n' characters, you could read fixed-size blocks to avoid this internal copying.

It's awkward to read 1000 bytes at a time.  You would be better off reading chunks that are aligned with the blocks on the disk.  A better choice would be 1024.

You could use the perror() function to report why I/O operations failed.  Technically, fgets() could fail too, so you should check for that.

It's a good habit to ensure that your fopen() is paired with fclose().

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

#define SIZE 1024

int main(void) {
    const char filename[] = "test";
    FILE *in_file;
    char buffer[SIZE + 1], lastchar = '\n';
    size_t bytes;
    int lines = 0;

    if (NULL == (in_file = fopen(filename, "r"))) {
        perror(filename);
        return EXIT_FAILURE;
    }

    while ((bytes = fread(buffer, 1, sizeof(buffer) - 1, in_file))) {
        lastchar = buffer[bytes - 1];
        for (char *c = buffer; (c = memchr(c, '\n', bytes - (c - buffer))); c++) {
            lines++;
        }
    }
    if (lastchar != '\n') {
        lines++;  /* Count the last line even if it lacks a newline */
    }
    if (ferror(in_file)) {
        perror(filename);
        fclose(in_file);
        return EXIT_FAILURE;
    }

    fclose(in_file);
    printf("Number of lines in the file is %i\n", lines);
}


The for loop above is a bit tricky for beginners, but should be acceptable for experienced C programmers.  The loop


for (char *c = buffer; (c = memchr(c, '\n', bytes - (c - buffer))); c++)



means:


Search for the next newline, starting from the pointer c, in the remaining bytes - (c - buffer) bytes that have been read but not examined yet.
If a newline is found, make c point to the position just after it.
If no newline is found, then we're done with this chunk.  Try reading more input then.


The extra set of parentheses around c = memchr(…) is an indication to the compiler and to other programmers that the = is indeed intentional, and is not supposed to be ==.