Exercise 1-16

Revise the main routine of the longest-line program so it will correctly print the length of arbitrarily long input lines, and as much as possible of the text.

When getline comes across a line that is longer than lim, it reads in lim - 1 characters—the limth element is saved for \0—and hence getline will return lim - 1. In order to make sure that our line was not actually lim - 1 characters long, we ensure that the last character (second-to-last element) is not a newline. We can combine these two conditions to detect when a line's length has exceeded lim, in which case we read in characters with getchar until we reach a newline, incrementing len for every character. Once our program finishes reading in input, if max is greater than or equal to MAXLINE, we also print its value alongside the longest line.

    #include <stdio.h>
    #define MAXLINE 1000    /* maximum input line size */
    
    int my_getline(char line[], int maxline);
    void copy(char to[], char from[]);
    
    /* print longest input line */
    main()
    {
        int len;            /* current line length */
        int max;            /* maximum length seen so far */
        char line[MAXLINE];     /* current input line */
        char longest[MAXLINE];  /* longest line saved here */
    
        max = 0;
        while ((len = my_getline(line, MAXLINE)) > 0) {
            /* line length exceeds MAXLINE */
            if (len == MAXLINE - 1 && line[MAXLINE - 2] != '\n') {
                while (getchar() != '\n')
                    ++len;
                ++len;  /* include newline */
            }
            if (len > max) {
                max = len;
                copy(longest, line);
            }
        }
        if (max > 0)    /* there was a line */
            printf("%s", longest);
        if (max >= MAXLINE)
            printf("...\nLength: %d\n", max);
        return 0;
    }

Note: on POSIX systems (such as macOS and GNU/Linux), there exists a function called getline within the C library. This function is not part of the C standard—for example, you will not find it on Windows, but in order to alleviate any potential conflicts and ambiguity, we have renamed our version of getline to my_getline.

Note: you may have noticed that the function body for both getline and copy is missing. We have done this because we think the implementation details of the functions detract from the exercise itself. In the actual source files, you will find that the body of getline is present so that the code will actually compile.