On 7 Nov 2003 04:31:20 -0800
(Jeff) wrote:
> Hello everybody,
>
> I was doing one of the exercises in the K&R book, and I got something
> really strange. Here's the source code:
>
> /*
> * Exercise 2-2 from the K&R book, page 42
> */
> #include <stdio.h>
>
> enum loop_control { EXIT, CONTINUE };
>
> int getline (char s[], int lim)
size_t would be better than int, look up size_t in K&R.
> {
> short int loop = CONTINUE;
I would suggest
enum loop_control loop = CONTINUE;
A good debugger might then show you the enumeration used. If memory was
tight and you wanted to save space then you could make loop a char, but
I can't see any reason for a short in this case.
> unsigned int i = 0;
Again, size_t would be a better type.
> int c;
>
> while (loop) {
> c = getchar();
> if (i == (lim - 2))
You have a problem if lim == 1.
> loop = EXIT;
> else if (c == EOF)
> loop = EXIT;
> else if (c == '\n')
> loop = EXIT;
Why two seperate ifs?
> else
> s[i++] = c;
> }
>
> if (c == '\n')
> s[i++] = c;
You could have handled this when you detected the newline above. Also,
if you hit the lim-2 without a newline you have just thrown away a
character.
> s[i] = '\0';
A problem if lim==1, even if that is a silly value.
>
> return (i);
> }
>
> The strange thing is that lim doesn't seem to control anything at all.
> I compiled it using GCC under cygwin on a windows 98 system (I added a
> simple main() function that gets a line using getline() and then
> prints it).
> The strange thing is that even when I put a very small value for lim,
> say 10, I can still get very big strings into it without it crashing.
> Here's an example output:
> $ gcc -o ex exercise2-2.c
> $ ./ex
> 123333333333333333
> 1233333333333333
> fdkjghfgsfgkjsdf
> fdkjghfgfgkjsdf
If you used the following main you would get a better idea.
#define SIZ 5
int main(void)
{
char buf[SIZ];
int len;
while (1) {
len = getline(buf,SIZ);
printf("\"%s\" %d\n",buf,len);
}
return 0;
}
Here is a possible rework of your code. Note, I've reworked your code
rather than trying to solve the exersize, so it may not be what you
actually want.
int getline (char s[], size_t lim)
{
enum loop_control loop = CONTINUE;
size_t i = 0;
int c;
while (loop) {
c = getchar();
if (c == EOF)
loop = EXIT;
else {
s[i++] = c;
if (c == '\n' || i+1 >= lim)
loop = EXIT;
}
}
if (i<lim)
s[i] = '\0';
return (i);
}
HTH.
--
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.