Printing the first 10 lines of a file in C with open() and read()

I’m trying to print the first 10 lines from a txt file using the functions open() and read(). So far I’ve managed to print the entire file, but I’m having problems with stopping the code when I have reached the end of line 10. What should I do?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int main(){
    int fd = open("a.txt", O_RDONLY);
    if(fd < 0){
        printf("Error: %d\n", errno);
        perror("");
    }

    char *c = (char*)calloc(100, sizeof(char));
    ssize_t res;
    int max = 0;

    while(res = read(fd, c, 1) && max < 10){
        if(res < 0){
            printf("Error: %d\n", errno);
            perror("");
        }

        c[res] = '\0';
        if(c[res] == '\n'){
            max++;

        }
        printf("%s", c);

    }

    close(fd);
    return 0;
}

>Solution :

The following always sets position res to '\0', and then immediately checks if it is '\n'.

c[res] = '\0';
if(c[res] == '\n'){
    max++;
}

This will never hold true. As such, max never increases, and you will read the entire file.

Additionally, res holds the result of read(fd, c, 1) && max < 10. It requires parenthesis to isolate the assignment to the correct result: (res = read(fd, c, 1)) && max < 10 (although, switching the order of these would help to avoid unnecessary reads).

If you’re reading the file one byte at a time, there is no need to allocate such a large buffer. A single byte of storage will suffice. Instead of using "%s to print a NUL terminated string, you can use "%c" to print a single character (or use write).

An example using read and write:

#include <unistd.h>
#include <fcntl.h>

int main(void) {
    char byte;
    int newlines = 0;
    int fd = open("a.txt", O_RDONLY);
                                    
    while (newlines < 10 && read(fd, &byte, 1) > 0) {
        /* alternatively: printf("%c", byte); */
        write(STDOUT_FILENO, &byte, 1);

        if (byte == '\n')
            newlines++;
    }

    close(fd);
}

Leave a Reply