printf bad ?
Henry Spencer
henry-lqW1N6Cllo0sV2N9l4h3zg at public.gmane.org
Fri Mar 18 20:50:45 UTC 2005
On Fri, 18 Mar 2005, Peter wrote:
> printf "%05d" 08
> it says 'invalid number' for any number of 0's before the 8. Why does it
> think it's octal ?!
Because the syntax of the arguments (after the format string) to the
printf command is defined -- in the POSIX standard -- to be the same as
that of C constants, with some minor extensions, and in C, a leading 0
means an octal number. (The fact that the FSF's documentation for the
printf command fails to discuss this is a documentation bug.)
> printf "%05d" 10#08
> -bash: printf: 10#08: invalid number
>
> (according to the bash manual that notation should force decimal - it
> does not - not in quotes and not in ticks and not with a
> backslash-escaped '#').
That notation is for the $(( )) construct, the shell's built-in expression
evaluation; it doesn't apply everywhere. If you try this:
printf "%05d" $((10#08))
you'll find that it works.
> I wrote a small C program to test atoi, strtod and strtoul and the
> latter is broken (is it ?). E.g.:
> plp at plp:~/tc$ ./1 08
> atoi: 8
> strtod: 8.000000
> strtoul: 0
Does your program check to see whether strtoul() actually consumed the
whole string? If you specified 0 as the "base" argument of strtoul(),
then it follows the C rules, so a leading 0x means hex, a leading 0
followed by a valid octal digit is octal, and otherwise the 0 is the
whole number and there's some trash following it.
atoi() doesn't show this behavior because its input is always decimal by
definition. strtod() doesn't because there is no octal floating-point
format, so it's taking 08 as decimal.
> I take this to mean that strtoul() assumes the lowest conversion base it
> can use if the third argument is 0.
No. Quoth "man strtoul" (after a discussion of possible leading white
space and sign):
If base is zero or 16, the
string may then include a `0x' prefix, and the number will
be read in base 16; otherwise, a zero base is taken as 10
(decimal) unless the next character is `0', in which case
it is taken as 8 (octal).
In other words, with a zero base, a leading 0 not followed by x means
octal, period.
> It should look at the
> whole string and match the highest base it can, starting from the last
> character that is not convertible with any base, imho.
That is an interesting notion, but it is *not* the specification for
strtoul(). You don't have to guess how these things work; it's
documented.
Henry Spencer
henry-lqW1N6Cllo0sV2N9l4h3zg at public.gmane.org
--
The Toronto Linux Users Group. Meetings: http://tlug.ss.org
TLUG requests: Linux topics, No HTML, wrap text below 80 columns
How to UNSUBSCRIBE: http://tlug.ss.org/subscribe.shtml
More information about the Legacy
mailing list