drjimmie1976 drjimmie1976 -4 years ago 207
C Question

fgets implementation (K&R)

I'm new to programming, starting off with Objective-C but have decided to go back to basics before progressing further. I'm spending some time on C, and am struggling through pointer confusion. My question is about how K&R says fgets is implemented (p165, 2nd ed.) Code below is direct from the text with a couple of my comments.

char* fgets(char* s, int n, FILE *iop)
register int c;
register char* cs;
cs = s;

while(--n > 0 && (c = getc(iop)) != EOF)
// put the input char into the current pointer position, then increment it
// if a newline entered, break
if((*cs++ = c) == '\n')

*cs = '\0';
return (c == EOF && cs == s) ? NULL : s;

1) We pass a char* s to the fgets function, at whose location we store the user input. Why is there a need to declare the local char* cs - and then initialise it to s? Why can't we directly manipulate/add to s within the if statement? Seeing as cs is initialised to point s, isn't adding the chars to cs exactly the same thing?

2) Tied in with the above...When the function returns, a test is made to see if cs == s. Why is this necessary?

I think I may be missing something very fundamental - I did check SO and Google but can't quite figure it out. Thanks!

Answer Source

It's because of the check on the last line, cs == s. This comparison checks the modified pointer cs against the original s to see if we've read any character. If we haven't then we return NULL.

By using cs throughout the original pointer s is preserved. If s were directly manipulated (*s++ instead of *cs++) then we'd have to find another way to check whether any characters were read.

One can also argue that it's a good practice to leave function parameters alone and treat them as const. Some programmers follow this practice as a way to enhance code clarity.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download