The use of EOF (Ctrl + D) in getchar() in C

109 views Asked by At

I'm going through section 1.9 in K&R, I don't understand the use of EOF in the code implemented below

#include <stdio.h>
#define MAXLINE 1000            /* maximum input line length */

int mymygetline(char line[], int maxline);
void copy(char to[], char from[]);

/* print the longest input line */
int 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 = mymygetline(line, MAXLINE)) > 0) {
        if (len > max) {
            max = len;
            copy(longest, line);
        }
    }
    if (max > 0)                  /* there was a line */
        printf("%s", longest);
    return 0;
}

/* mymygetline: read a line into s, return length */
int mymygetline(char s[], int lim)
{
    int c, i;
    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}

/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[], char from[])
{
    int i;
    i = 0;
    while ((to[i] = from[i]) != '\0')
        ++i;
}

What I tried:

  • The initial program run well with difference line of input mark with "\n" is easy to understand
  • When I tried to enter EOF firsttime inline, it just end recent input stream and set getchar() in waiting mode for input stream.

Question:

  • When I enter EOF twice inline, does the first EOF just act like a "\n" or some other mechanism or I just missing something here.
1

There are 1 answers

0
pts On

Here is how a keypress propagates to your code (mymygetline()) function:

  • The user presses the key.
  • The keyboard receives the keypress and sends some kind of event containing the keycode to the Unix-like operating system.
  • The operating system figures out that the event should be routed to a terminal (this includes terminal emulator windows on a GUI). The operating system converts the event to a byte sequence and sends it to the terminal.
  • The terminal may do some more transformations and buffering. By default, it buffers (i.e. doesn't let through) bytes until a newline or something special (such as the character corresponding to Ctrl-D) is received.
  • The libc code (called by getchar(3)) in the program reads a sequence of bytes from the terminal. While the terminal is buffering, the libc code blocks in the read(2) system call. As soon as the terminal flushes, read(2) receives many bytes at once, typically an entire line followed by a newline character, or an EOF indicator (read(2) returns 0).
  • Your code (mymygetline()) receives the bytes read by read(2) one byte at a time from getchar(3). As soon as no more bytes are available, libc code calls read(2) again, which blocks until more bytes come.

If the user presses Ctrl-D, read(2) returns the bytes buffered so far (if any), a subsequent read(2) (triggered by the second Ctrl-D) returns 0, which causes getchar(3) to return EOF.