thankgodforthissite
thankgodforthissite

Reputation: 25

K&R - Section 1.9 - Character Arrays (concerning the getline function)

My question is concerning some code from section 1.9-character arrays in the Kernighan and Ritchie book. The code is as follows:

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

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

/* get line: read a line into s, return length */
int getline(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;
}

My question is about the getline function. Now looking at this following output from my command line as a reference:

me@laptop
$ characterarray.exe
aaaaa
a
aaaaaa
^Z
aaaaaa

me@laptop
$

When I type in the first character which is 'a', does the character 'a' go through the for loop, in the getline function, and initialize s[0] - s[998] = a ? And my second part of the question is once the program leaves the for loop and goes to the

s[i] = '\0'
return i;

wouldn't it be initialized s[998] = '\0' and the return integer is 998? I've spent over an hour staring at this problem and I can't seem to grasp what is going on.

Upvotes: 2

Views: 813

Answers (2)

Andrei Nikolaenko
Andrei Nikolaenko

Reputation: 1074

Character 'a' does not go through the for loop. Look here:

for (i=0; i<lim-1 && ((c=getchar()) != EOF) && c != '\n' ; ++i) 

c = getchar() is where your program stops and waits for user input -- not just once, but in a loop! This is a condition of continuing the for loop, and each time it is checked, a getchar() is called. The loop goes only one char at a time. Each time a char is added to the current end of an array (indicated by i) and the loop breaks when a newline symbol is entered or when a limit size is reached. This is very compact code but it is kind of oldschool C coding which is not very readable these relaxed days. It can be broken into following parts:

i = 0;
while(i < lim - 1) {
    c = getchar();
    if (c == EOF || c == '\n') break;
    s[i] = c;
    ++i;
}
s[i] = '\0'; 
return i;

(also I don't think a newline symbol is needed to be included in the string, so I omitted the

if (c == '\n') {
    s[i] = c; 
    ++i;
}

part.)

Upvotes: 0

nt-complete
nt-complete

Reputation: 519

Here is how the input is working in the for-loop.

Before the for-loop, the array s is empty(ish. It's full of whatever garbage is in that memory). If you type in a single a and hit enter, the for-loop goes through 2 characters 'a' and '\n'. For 'a', the variable c becomes 'a' from getchar() in the for-loop parameters, and that gets saved in the i spot (which is 0) of s. So, the array s is now s[0] = 'a' and the rest of s has random garbage in it.

Then c becomes '\n' from getchar(). This stops the for-loop because of the c != '\n' check. The if-statement has s[i], where i is 1, become '\n' and i bumps up to 2.

Now s is

s[0] = 'a' s[1] = '\n'

getline finishes up by making s[2] be '\0', which is the end of string character, and returns i.

Your end result is

s[0] = 'a' s[1] = '\n' s[2] = '\0'

and i, your length, is 2.

Upvotes: 0

Related Questions