Guessing buffer size needed for sprintf beforehand
Chris Torek
chris at mimsy.UUCP
Wed May 4 01:30:52 AEST 1988
In article <136 at insyte.uucp> jad at insyte.uucp (Jill Diewald) writes:
>... sprintf ... requires my knowing how big a buffer to supply.
>The IO module of our program needs to sprintf into its internal
>output buffer - which is dynamically allocated. ... The IO routine
>does not know how many characters there are to print until sprintf
>returns that number, by then it it too late!
Welcome to the `we hate sprintf' club :-) . Alas, there is no portable
way to do this. There *is* one reasonably portable solution, but it
may be slow. If you have a `function oriented stdio', there is a
convenient and fast solution, but it is not portable.
>One solution is to fprintf into a file opened to be /dev/null.
>This requires two calls to the c print fuctions, one to get the
>size and the second to actually print.
By the time you reach a routine that takes a `va_list' argument,
it is too late to scan the argument list twice: there is no way
to `back up' the va_list parameter. So, while this would get
you a suitable count, it would then be too late to use that count.
>Is there another approach?
Here is one:
static FILE *sfile; /* dynamic sprintf string file */
/*
* open a temp file in "w+" mode, or perhaps even
* in "w+b" mode; abort if it cannot be opened.
*/
void
dynopen()
{
/* you supply the details */
}
/*
* dynamically create a string holding the result from a printf.
*/
char *
dynsprintf(fmt, ap)
char *fmt;
va_list ap;
{
static FILE *sfile;
int count, c;
char *ret, *cp;
if (sfile == NULL)
dynopen();
/* write the arguments to the temp file, and count characters */
rewind(sfile);
count = vfprintf(sfile, fmt, ap);
if (count == EOF) ... handle error
/* make room */
ret = malloc((unsigned)count + 1);
if (ret == NULL) ... do something
/* read back the result */
rewind(sfile);
cp = ret;
while (--count >= 0) {
if ((c = getc(sfile)) == EOF) ... ??? why?
*cp++ = c;
}
*cp = 0;
return (ret);
}
void
dynclose()
{
if (sfile != NULL) {
(void) fclose(sfile);
... remove temp file
}
}
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.unix.questions
mailing list