notes on sprintf (was Re: [CIRCLE] kinda dumb question...)

From: Chris Gilbert (chris@buzzbee.freeserve.co.uk)
Date: 02/02/00


Rohan Wallace wrote:
>
> Try this:
>
> >     sprintf(buf2," [%d]\n\r", num);
> >                 strcat(buf, buf2);
> >             }
> >
>
> Replace the above with:
>
>       sprintf (buf, "[%d] %s\n\r", num, buf);
>               }

Not trying to sound picky, this is more of note to newbie coders really,
but with a dumb sprintf you might find that it either:
a: clears the target buffer, so you end up with:
buf = "[1] \n\r"
b: starts to fill the target buffer, but never ends:
start:
buf = "fred"
after [%d] copy:
buf = "[1] "
then start copying buf into itself:
buf = "[1] ["
repeat copy:
buf = "[1] [1] [1] [1] [1]...."
eventually it'll overflow a buffer.

however something that copies the buffers first will produce:
"[1] fred\n\r"
as is wanted.

This is partly why you don't use:
sprintf(buf, "%s new text", buf);
as it might clear the buf first, but it's also inefficient, should use:
sprintf(buf + strlen(buf), " new text");

or a useful feature of sprintf is it returns the number of bytes copies
so you can be cunning and do:

int a = 0;
a += sprintf(buf + a, "some stuff",  ...);
a += sprintf (buf + a, "some more stuff", ...);

(and you can check locally if the buffer overflowed by checking the
value of a, very useful for loops where you run the risk of filling a
buffer)


also of note is that \n\r is incorrect by the telnet protcol (that's a
bug with the original patch though) it should be \r\n.

(oh and I realised my lost post is wrong it'll put the line endings in
the wrong place, but I'll leave that as an exercise for the reader ;)

Cheers,
Chris


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     |  http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html  |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 04/10/01 PDT