setting MAX characters emitted in printf() functions?

D

David Mathog

Is there some method for restricting the maximum number of
characters that will be emitted by a printf() function?
Where printf() here is generic and refers to sprintf, fprintf, etc.

Here's an example of where this would be used (partial code!)

double thevar;
char abuf[256];
int oc;

/* thevar is set by some code here */

oc = sprintf(abuf,"%f",thevar);

The problem with this code is that even though abuf can hold
256 characters on some platforms a double is even larger than that,
and this results in sprintf writing off the end of abuf and over
other variables. I'm not entirely sure that one can predict
at run time the maximum number of digits needed for a double
unless perhaps the C standard specifies this. Unlike integer
types (where sizeof() gives the relevant info) doubles
could conceivably have different fractions of the bits in the
exponent.

Yes, this is for fixed width usage and basically I'd
be quite happy with something similar to the old Fortran overflow
method, where a field that is too big is just filled with
a row of asterisks. Since that seems not to be implemented in C
the closest I've come is to allocate a largish array and look
at the oc value set by sprintf(), then write * instead of the
string containing the formatted variable if the desired field
width is exceeded.

Thanks,

David Mathog
(e-mail address removed)
 
D

Dave Vandervies

Is there some method for restricting the maximum number of
characters that will be emitted by a printf() function?
Where printf() here is generic and refers to sprintf, fprintf, etc.
[snip]

Since that seems not to be implemented in C
the closest I've come is to allocate a largish array and look
at the oc value set by sprintf(), then write * instead of the
string containing the formatted variable if the desired field
width is exceeded.

If you can depend on having access to C99 or any of several pre-C99
implementations that provide it as an extension (including both GNUC and
MSVC++, which are the two I have readily available to check), you can
do something like this using snprintf instead of sprintf, which reduces
the size of the array you need to sprintf into.

C99 snprintf returns the number of characters that would have been
written if the requested limit was high enough, so you can use the same
check you'd use with sprintf; GNUC snprintf and MSVC++ _snprintf return
negative values if they truncate the output, so you'd want to check
for that instead of a return value greater than the size you ask for.
(The C99 behavior is more useful in general but both give you the
information you need here.)


I don't know of any way to limit the size of the output of any of the
printf family of functions other than snprintf.


dave
 
D

Dave Thompson

Is there some method for restricting the maximum number of
characters that will be emitted by a printf() function?
Where printf() here is generic and refers to sprintf, fprintf, etc.
In addition to Dave Vandervies' answer about snprintf, which applies
to the whole function call (format) and only to _s_printf:
Here's an example of where this would be used (partial code!)

double thevar;
char abuf[256];
int oc;

/* thevar is set by some code here */

oc = sprintf(abuf,"%f",thevar);

The problem with this code is that even though abuf can hold
256 characters on some platforms a double is even larger than that,
and this results in sprintf writing off the end of abuf and over
other variables. I'm not entirely sure that one can predict
at run time the maximum number of digits needed for a double
unless perhaps the C standard specifies this. Unlike integer
types (where sizeof() gives the relevant info) doubles
could conceivably have different fractions of the bits in the
exponent.
I assume you mean the representation of some (relevant) double values
is larger than 256-1=255 characters, which is what matters here.

If you have values over a large range, is there a reason you don't use
'scientific' notation -- %e or %g? Those have no good reason to use
more than DBL_DIG +1 or maybe 2 'mantissa' digits (and you can force
that using %.*e) plus the sign, point, and exponent which together
should never exceed about 7 (and can be determined if critical).

If you really want all possible values in %f notation, you could
allocate/allow DBL_MAX_10_EXP plus a slop factor.

Those values DBL_* and similarly FLT_* LDBL_* etc. are (possibly)
implementation dependent but fixed for one implementation at or before
compile time when they are available in said:
Yes, this is for fixed width usage and basically I'd
be quite happy with something similar to the old Fortran overflow
method, where a field that is too big is just filled with
a row of asterisks. Since that seems not to be implemented in C

Right, it's not. *printf has _minimum_ fields widths but _maximum_.
(*scanf does have maximum _input_ widths, just to confuse you.)
the closest I've come is to allocate a largish array and look
at the oc value set by sprintf(), then write * instead of the
string containing the formatted variable if the desired field
width is exceeded.
Or just do the comparison yourself:
if( fabs(x) >= 1.e6 ) printf ("%9s", "overflow");
else printf ("%.6f", x);
Thanks,

David Mathog
(e-mail address removed)

Or, use one of the compiler suites or combinations that supports C and
Fortran (including gcc which has g77 and two competing f95's under
development) and do the (relevant) output in Fortran.

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top