for statement question

rmtogether
rmtogether used Ask the Experts™
on
Hi,
could someone explain the following code for me (I don't get the line with ? mark) thank you very much!

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

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

   /* print the 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;
   }



 /* getline:  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;
   }
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Awarded 2006
Top Expert 2006
Commented:
 for (i=0;
 -> start loop with i=0

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

-> continue while:
- i is less than lim-1 AND
- (get a byte, assign the byte to c)
- c is not end-of-file AND
- c is not end-of-line

 ++i)
-> Increment i by one with each iteration of the loop
Awarded 2006
Top Expert 2006

Commented:
http://www.sysprog.net/cloop.html    C loops

for (INITIALIZATION; CONDITION; ITERATION)
   {
   BODY
   }
Awarded 2006
Top Expert 2006

Commented:
\n means newline:
"The C programming language provides the escape sequences '\n' (newline) and '\r' (carriage return). " (http://en.wikipedia.org/wiki/CRLF)
How to Generate Services Revenue the Easiest Way

This Tuesday! Learn key insights about modern cyber protection services & gain practical strategies to skyrocket business:

- What it takes to build a cloud service portfolio
- How to determine which services will help your unique business grow
- Various use-cases and examples

Author

Commented:
why use lim-1 ? why not just use lim?
Awarded 2006
Top Expert 2006

Commented:
Arrays of course start at 0 index, not 1, so s[0] would hold the first byte etc., but that doesn't seem to be a factor in this case

lim shoud work too. You can try it & test it with MAXLINE set to a lower number like 50

I think it uses lim-1 to save a step: Since you don't need to read in the newline character, just skip it.

Hi rmtogether,

It's lim-1 because you are building a string so you need to leave room for the null terminator on the end.

       s[i] = '\0';

If it was i<lim then at the end of the loop i will be == lim so this line will write beyond the limit specified.

Paul

Author

Commented:
hi,
in the for statement has c!='\n', but insie brace has c=='\n'. I am confused about this.?
The loop walks through the line and stops either when the character it is looking at is a return or it hits the end of the file.

The check for c=='n' is just making sure it doesnt add the character if end of file is reached.

Paul
Awarded 2006
Top Expert 2006

Commented:
!=      -> not equals
so: continue loop if c is not equal to '\n'

==      -> equals
so: run the 'if' block only if the current byte is a '\n'

So, it seems that the if block will never get executed, and so the if block is superfluous...
Change of code: If you want to include the newline character in s, then remove the c!='\n' condition; else remove the if block.

I'll leave it for Paul to verify or correct my hunch.  [Thanks Paul about the '\0'. I forgot to read beyond the loop.]
Top Expert 2006
Commented:
>in the for statement has c!='\n', but insie brace has c=='\n'. I am confused about this.?
The != check is the for loop and == check is outside the for loop ...

The for loop can temrinate on one of these conditions
a) EOF was read
b) Newline was read

In case newline (\n) was read then at the end of loop, array line will NOT contain \n, and c will contain \n.

The check AFTER for loop " if (c == '\n')" checks if this was the case ... If yes, then it adds newline to buffer. This is similar in behavior to fgets that reads in newline too.

However, there is a potential bug in the program ... It loops to lim, i.e. it has valid locations from 0 to lim-1 .. In the for loop it fills up all locations from 0 to lim -2 (loop says < l-1) and after loop it potentially adds two characters (\n and \0) while it has memory for only one.

This is a buffer overrun and can cause crash/corruption
Top Expert 2006

Commented:
The for loop can temrinate on one of these conditions
a) EOF was read
b) Newline was read
or lim-2 characters were read ... Very important but not significant for demonstrating why the if statement is there

Author

Commented:

What is the purpose of the getline function.
Is it used for return the length of each line of a input file?
Top Expert 2006

Commented:
Yes, that is what the function is being used for ...

Purpose of getline
 /* getline:  read a line into s, return length  */

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial