-1
#define MAXLINE 1000
char pattern[] = "ould";
main()
{
    char line[MAXLINE];
    int found = 0;

    while (getline(line,MAXLINE) > 0)
       if (strindex(line, pattern) >= 0 ) {
          printf("%s", line);
          found ++;
       }
    return found
}

Why does that while loop go on forever? getline(line,1000) would, as I barely understand it, return the length of the line, and "append it" (?) to MAXLINE, making a number larger than 1000, depending on the line length... why would that ever dip below zero?

I read that getline returns -1 if "unsuccessful", when would that be? When would line not be read?

This is on page 69 of Kernighan. I've been skipping around the book, and I'm currently backtracking to see where I missed something.

"Describe what you tried, what you expected to happen, and what actually resulted. Minimum 20 characters."

Martin Kristiansen
  • 9,875
  • 10
  • 51
  • 83
  • 4
    What happens when `stdin` is closed? Either by hitting Ctrl-D or by having it piped from a file that ends? – ShadowRanger Dec 21 '22 at 02:28
  • Is `getline` a function that you have defined yourself? If that is the case, then please show us the code of that function. – Andreas Wenzel Dec 21 '22 at 02:36
  • @AndreasWenzel `getline` is a function that pops up a couple times in K&R/2e (chapters 1 & 4). – Oka Dec 21 '22 at 02:41
  • @AndreasWenzel thank you! This is it, getline is defined in the standard library a totally different way than in the book. Appreciated, all! (er; how do I mark as solved?) – Fidgety Meditation Dec 21 '22 at 02:56
  • 1
    @FidgetyMeditation: The ISO C standard library does not define a function with the name `getline` at all. However, POSIX platforms (e.g. Linux) do define a function by that name. But you are correct that this definition is different from the one in the K&R book. The most similar function in the ISO C standard library is probably the function [`fgets`](https://en.cppreference.com/w/c/io/fgets). – Andreas Wenzel Dec 21 '22 at 03:03
  • *I've been skipping around the book* - Stop doing that, and start from the beginning and work your way through. Skipping around means that you miss important concepts. Also, you need to provide a [mre] here, and that includes all the code that you've written (whether it's from the book or not), so that we can see if you've introduced a typo or missed a line. Any code that is not part of the standard libraries should be in your post. – Ken White Dec 21 '22 at 04:47
  • Why are you trying to learn modern C from K&R C? – Dúthomhas Dec 21 '22 at 04:51
  • Skipping the whole book might be the better idea indeed. It's as outdated as a computer from the 1970s. – Lundin Dec 21 '22 at 07:28

2 Answers2

1

The version of getline shown on page 69 of K&R Second Edition is defined as:

/* getline: get line into s, return length */
int getline(char s[], int lim)
{
    int c, i;

    i = 0;
    while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
        s[i++] = c;
    if (c == '\n')
        s[i++] = c;
    s[i] = '\0';
    return i;
}

From this we can see that one of the conditions that must be met for the function to continue consuming characters from the stdin stream is that the returned character does not equal the constant value EOF.

(c=getchar()) != EOF

EOF, or end-of-file, indicates that there is no more data to be read from the stream. See What is EOF in the C programming language? for additional details.

In the event that getchar returns EOF the very first time it is called in getline, i will never increment beyond 0, and the function will return zero.

This version of getline cannot return -1.

The condition you have shown

while (getline(line,MAXLINE) > 0)

will cause this loop to stop when the return value is less than or equal to zero. In other words, when getline indicates it has read no data.

Oka
  • 23,367
  • 6
  • 42
  • 53
0

I'm assuming you are using the getline and strindex defined in the book:

/* getline: get line into s, return length */
int getline(char s[], int lim)
{
    int c, i;

    i = 0;
    while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
        s[i++] = c;
    if (c == '\n')
        s[i++] = c;
    s[i] = '\0';
    return i;
}

/* strindex: return index of t in s, -1 if none */
int strindex(char s[], char t[])
{
    int i, j, k;

    for (i = 0; s[i] != '\0'; i++) {
        for (j=i, k=0; t[k] != '\0' && s[j] == t[k]; j++, k++)
            ;
        if (k > 0 && t[k] == '\0')
            return i;
    }
    return -1;
}

As you can see getline reads until it reaches end of file(EOF). If you are running the program on the command-line, your program is waiting for this signal from standard in, you can send this signal manually by pressing Control-d.

if you cat a file into the program:

$ cat test.txt | ./your program

the end of file value it sent, at the end of the file.

Martin Kristiansen
  • 9,875
  • 10
  • 51
  • 83