GNU bug report logs -
#10782
zero padding does not work in case of strings
Previous Next
Reported by: Praveen A <pravi.a <at> gmail.com>
Date: Fri, 10 Feb 2012 18:54:02 UTC
Severity: normal
Tags: notabug
Done: Eric Blake <eblake <at> redhat.com>
Bug is archived. No further changes may be made.
Full log
Message #12 received at 10782-done <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
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 eblake <at> redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[signature.asc (application/pgp-signature, attachment)]
This bug report was last modified 13 years and 161 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.