K&R Exercise 1.16 - Limitation on line length

2019-02-16 10:34发布

问题:

I'm learning C from K&R's "The C Programming Language" book. I'm doing the exercises specified in the book. I'm on exercise number 1.16, but I don't understand it.

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.

My questions:

  1. "...as much as possible of the text..." - is there some limitation on string length? Maybe in standard headers there's a variable with the max allowed value of string length?

  2. "...the length of arbitrarily long input lines..." - but in the code MAXLINE is defined as 1000. It is limited size too. I see some solutions here, but in my opinion it is not solution decision, since on the former there is a restriction on length of a line (1000 characters).

Maybe I don't understood the task. My understanding is I must remove the 1000-character limitation.

回答1:

It's a pretty early exercise in K&R, you're just supposed to do some minor changes to the code, not a total redesign of the code.

  1. "...as much as possible of the text..."

    is up to you to interpret. I'd do it by printing what's stored in the longest buffer. i.e. print out up to 1000 characters of the line. Again, it's an early exercise, with little introduction to dynamically allocated memory yet. And at the time K&R was written, storing away arbitrarily long text lines wasn't as feasible as it is today.

  2. "...the length of arbitrarily long input lines..."

    Is a hard requirement. You're supposed to find the correct length no matter how long it is (at least within the bounds of an int. )

One way to solve this problem is:

  • After the call to getline(), check if the last character read into the line buffer is a newline ('\n')
  • If it is, you read a complete line. The len variable is the correct length of the line(the return value of getline(), and no special consideration is needed compared to to original code.
  • If it is not , you did not read the entire line, and need to hunt for the end of this line. You add a while loop, calling getchar() until it returns a newline (or EOF), and count the number of characters you read in that loop. Just do len++ to count.
  • When the while loop is done, the new len is now the actual length of the line, but our buffer just has the first 999 characters of it.
  • As before, you store away (the copy() function call) the current line buffer (max 1000 chars) if this line is the longest so far.
  • When you're done, you print out the stored line as before (the longest buffer) and the max variable for the length.
    • Due to the above mentioned while loop that max length is now correct.
    • If the longest line indeed was longer than 1000 chars. you at least print out those first 999 chars - which is "as much as possible".

I'll not spoil it and post the code you need to accomplish this, but it is just 6 lines of code that you need to add to the longest-line program of exercise 1-16.



回答2:

  1. On modern machines "as much as possible of the text" is likely to be all of the text, thanks to automatically line-wrapping terminal programs. That book was written when teletype terminals were still in use. There is no limitation on string length other than perhaps memory limitations of the machine you're working on.

  2. They're expecting you to add some kind of loop to read characters and look for newlines rather than assuming that a read into the MAXLINE sized buffer is going to contain a newline for sure.



回答3:

here is my version:

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;
    }
    if(c!=EOF)
    {
        while((c=getchar())!=EOF&&c!='\n')
            i++;
    }
    s[i]='\0';
    return i;
}
    #define MAXLINE 1000
    int len;
    int max;
    char line[MAXLINE];
    char longest[MAXLINE];

    max=0;
    while((len=getline(line,MAXLINE))>1)
    {
        if(len>max)
        {
            max=len;
            copy(longest,line);
        }
    }
    if(max>0)
    {
        printf("%d:%s",max,longest);
    }
    return 0;

for some unknown reasons ,the example code doesn't work in my pc particularly,when the condition is 'len>0',the loop won't end i think the main reason is that when you type nothing,but you still have to press enter,so it is received as '\n',and the len is 1; i think it satisfy the requirement that print the length of arbitrarily long input lines, and as much as possible of the text. And it works like this