[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#10782: zero padding does not work in case of strings
From: |
Eric Blake |
Subject: |
bug#10782: zero padding does not work in case of strings |
Date: |
Fri, 10 Feb 2012 12:29:53 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20120131 Thunderbird/10.0 |
tag 10782 notabug
thanks
On 02/10/2012 11:52 AM, Praveen A wrote:
> $ printf %04d 12
> 0012$ printf %4d 12
> 12$ printf %04s 12
> 12$ printf %4s 12
> 12$
Thanks for the report. In printf(3), POSIX states the use of the 0
modifier with %s is undefined:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
"0 For d , i , o , u , x , X , a , A , e , E , f , F , g , and G
conversion specifiers.... For other conversions, the behavior is undefined."
Note that glibc silently ignores %04x, and gcc correctly warns about it
being fishy:
$ cat foo.c
#include <stdio.h>
int main() { printf("%04s\n", "hi"); return 0; }
$ gcc -o foo foo.c -Wall
foo.c: In function ‘main’:
foo.c:2:1: warning: '0' flag used with ‘%s’ gnu_printf format [-Wformat]
$ ./foo
hi
>
> It would be very useful if it works for strings too (I found this when
> trying to zero pad hex values in an ipv6 address). Now it requires an
> additional sed find and replace to get the desired result.
Note that you didn't even test coreutils - you tested the built-in
printf of your shell. Coreutils intentionally errors out on this
undefined behavior, to make it obvious that there is no sane documented
way to implement it:
$ /usr/bin/printf %04s 12
/usr/bin/printf: %04s: invalid conversion specification
Implementing %04s in coreutils, but not also in glibc, bash, dash, ksh,
and so forth, all at the same time, would just cause user confusion due
to the inconsistencies; plus, you would have to wait for those fixes to
propagate into your machine before you could rely on it. Rather, you
should patch your script to use %d or %x or other tricks in a manner
that works today:
# Use $(()) to convert hex to decimal, then 0-pad it back out to hex
$ printf %04x $((0x12))
0012
# given an arbitrary string in $1, add 0-padding if needed to extend
# it to at least 4 characters
$ f() {
case ${#1} in
0|1|2|3) printf %0$((4-${#1}))d%s 0 "$1" ;;
*) printf %s "$1" ;;
esac
}
$ f 12
0012
As such, I'm closing this bug report as something we won't change.
--
Eric Blake address@hidden +1-919-301-3266
Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature