0

I just posted this question, but I made quite a few mistakes in the way that I copied my code--so I'm going to repost it.

I'm trying to recreate a head command which prints the top of a file to standard output. I'm not sure if the command can take more options than -n (user specifies number of lines they want to be printed) and -c (user specifies number of chars they want to be printed), but those are the options I am implementing. I've finished most of the code, but can't quite get my program to print the correct number of lines when the -n option is used. Here's my code for the -n option:

char *buff = malloc(1024);
ssize_t szt = 0;
lines_read = 0;
fd = open(file.txt, O_RDONLY); // placeholder file.txt
while ((szt = read(fd, buff, sizeof(buff))) > 0) {
    for (int j = 0; j < sizeof(buff); ++j) {
        if (buff[j] == '\n') {
            ++lines_read;
            if (lines_read > n) {
                write(STDOUT_FILENO, buff, j);
                break;
            } // if
        }  // if
    } // for
} // for

Here's a link to my entire file head.c file. head

adamruehle
  • 23
  • 3
  • Won't this *not print* lines until `n` have been read? – Scott Hunter Oct 25 '22 at 19:08
  • To help us help you, you could provide some sample input, the sample values, the expected output, the actual output. Also, which line you think is not behaving the way you expect, and what you expected that line to do. Going through that might lead you to be able to answer your own question, but if not, the question has much more information for someone to quickly answer it for you. – jxh Oct 25 '22 at 19:21
  • 1
    There are multiple cases to handle when printing N lines, including: (1) there aren't N lines in the file; (2) the N lines take up less than 1 KiB (the size of your buffer); (3) the N lines take up more than 1 KiB (but no line is longer than 1 KiB); and (4) the N lines take up more than 1 KiB and some of the lines are longer than 1 KiB. Your code does not seem to be handling any of those. Note that when reading from a disk file, you won't get short reads until there is no more data left. With terminal input, you will get each line as a separate result from `read()` unless it's more than 1 KiB. – Jonathan Leffler Oct 25 '22 at 19:46
  • Also remember that `read()` and `write()` do not work with null-terminated strings; they deal in byte arrays with a count. – Jonathan Leffler Oct 25 '22 at 19:47

1 Answers1

1

I see one problem here (may be more). The sizeof operator

[y]ields the size in bytes of the object representation of the type of expression, if that expression is evaluated. [emphasis mine]

Therefore, sizeof(buff) returns always the size of char *, not taking into account the size of allocated memory for buff. This might be not what you expect. See also Newbie questions about malloc and sizeof.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user20276305
  • 95
  • 1
  • 7