Re: Weird problem

From: Mark Gordon (spamtrap_at_flash-gordon.me.uk)
Date: 11/07/03


Date: Fri, 7 Nov 2003 15:50:41 +0000

On 7 Nov 2003 04:31:20 -0800
agenthunt@netcourrier.com (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.


Relevant Pages

  • Weird problem
    ... I was doing one of the exercises in the K&R book, ... int getline ... The strange thing is that lim doesn't seem to control anything at all. ...
    (comp.lang.c)
  • Re: Weird problem
    ... You return an unsigned int from a function declared as returning int. ... > The strange thing is that lim doesn't seem to control anything at all. ... this version still uses the buffer provided by the caller ...
    (comp.lang.c)
  • Re: adapting getline
    ... int getline(FILE *fp, char *s, int lim) ... I see no obvious reason for such behavior, but the reason might be in the calling code. ...
    (comp.lang.c)
  • Re: [PATCH 1/3] Fix COW D-cache aliasing on fork
    ... situations that only happen when you fork() from a _threaded_ environment, ... program is neither very unlikely or strange. ... int main ... pid_t pid; ...
    (Linux-Kernel)
  • Re: 010 is 8 and not 10 :(
    ... karthikbalaguru wrote: ... I find that numbers beginning with a zero are evaluated in base 8. ... int numbers= {001, ... not as 10:(Strange:(:( ...
    (comp.lang.c)