'printf' with leading zeros in C - c

I have a floating point number such as 4917.24. I'd like to print it to always have five characters before the decimal point, with leading zeros, and then three digits after the decimal place.
I tried printf("%05.3f", n) on the embedded system I'm using, but it prints *****. Do I have the format specifier correct?

Your format specifier is incorrect. From the printf() man page on my machine:
0 A zero '0' character indicating that zero-padding should be used rather than blank-padding. A '-' overrides a '0' if both are used;
Field Width:
An optional digit string specifying a field width; if the output string has fewer characters than the field width it will be blank-padded on the left (or right, if the left-adjustment indicator has been given) to make up the field width (note that a leading zero is a flag, but an embedded zero is part of a field width);
Precision: An optional period, '.', followed by an optional digit string giving a precision which specifies the number of digits to appear after the decimal point, for e and f formats, or the maximum number of characters to be printed from a string; if the digit string is missing, the precision is treated as zero;
For your case, your format would be %09.3f:
#include <stdio.h>
int main(int argc, char **argv)
{
printf("%09.3f\n", 4917.24);
return 0;
}
Output:
$ make testapp
cc testapp.c -o testapp
$ ./testapp
04917.240
Note that this answer is conditional on your embedded system having a printf() implementation that is standard-compliant for these details - many embedded environments do not have such an implementation.

Related

How do I format a float to have 3 numbers before the decimal [duplicate]

I have a floating point number such as 4917.24. I'd like to print it to always have five characters before the decimal point, with leading zeros, and then three digits after the decimal place.
I tried printf("%05.3f", n) on the embedded system I'm using, but it prints *****. Do I have the format specifier correct?
Your format specifier is incorrect. From the printf() man page on my machine:
0 A zero '0' character indicating that zero-padding should be used rather than blank-padding. A '-' overrides a '0' if both are used;
Field Width:
An optional digit string specifying a field width; if the output string has fewer characters than the field width it will be blank-padded on the left (or right, if the left-adjustment indicator has been given) to make up the field width (note that a leading zero is a flag, but an embedded zero is part of a field width);
Precision: An optional period, '.', followed by an optional digit string giving a precision which specifies the number of digits to appear after the decimal point, for e and f formats, or the maximum number of characters to be printed from a string; if the digit string is missing, the precision is treated as zero;
For your case, your format would be %09.3f:
#include <stdio.h>
int main(int argc, char **argv)
{
printf("%09.3f\n", 4917.24);
return 0;
}
Output:
$ make testapp
cc testapp.c -o testapp
$ ./testapp
04917.240
Note that this answer is conditional on your embedded system having a printf() implementation that is standard-compliant for these details - many embedded environments do not have such an implementation.

Printing 0 in the place of blank space while using %5d in C [duplicate]

I have a floating point number such as 4917.24. I'd like to print it to always have five characters before the decimal point, with leading zeros, and then three digits after the decimal place.
I tried printf("%05.3f", n) on the embedded system I'm using, but it prints *****. Do I have the format specifier correct?
Your format specifier is incorrect. From the printf() man page on my machine:
0 A zero '0' character indicating that zero-padding should be used rather than blank-padding. A '-' overrides a '0' if both are used;
Field Width:
An optional digit string specifying a field width; if the output string has fewer characters than the field width it will be blank-padded on the left (or right, if the left-adjustment indicator has been given) to make up the field width (note that a leading zero is a flag, but an embedded zero is part of a field width);
Precision: An optional period, '.', followed by an optional digit string giving a precision which specifies the number of digits to appear after the decimal point, for e and f formats, or the maximum number of characters to be printed from a string; if the digit string is missing, the precision is treated as zero;
For your case, your format would be %09.3f:
#include <stdio.h>
int main(int argc, char **argv)
{
printf("%09.3f\n", 4917.24);
return 0;
}
Output:
$ make testapp
cc testapp.c -o testapp
$ ./testapp
04917.240
Note that this answer is conditional on your embedded system having a printf() implementation that is standard-compliant for these details - many embedded environments do not have such an implementation.

About printf format string in C

Let's take the following program:
#include <stdio.h>
int main()
{
long t =57 ;
printf("[%+03ld]", t);
}
and it's output:
[+57]
I am somehow confused: I told him to pad the output to width 3 (03ld), with zeroes, however it seems that if I force the output to put a plus sign before the number (+) it will not add the required zeroes if the length of the number is already 2 digits (as in 57). For numbers <10 it pads with 1 zero.
From http://www.cplusplus.com/reference/cstdio/printf/
(0) -> Left-pads the number with zeroes (0) instead of spaces when padding is specified (see width sub-specifier).
(+) -> Forces to preceed the result with a plus or minus sign (+ or -) even for positive numbers. By default, only negative numbers are preceded with a - sign.
(width) -> Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.
So I just need a clarification ... The (width) specifier from the quote above refers to the full length of the output string (ie: the characters that will be printed) controlled by this format specifier ("%+03ld") or the full length of the characters of the number that is going to be printed?
Yes, the width specifier refers to the width of the entire formatted result, +57 in your case. This makes it useful for printing columnar text for easy reading on screen (important if you're using C to write an old-school text utility!).
C standard is rather precise that converted value is taken a whole. From C11 §7.21.6/2 (emphasis mine):
The fprintf function writes output to the stream pointed to by stream,
under control of the string pointed to by format that specifies how
subsequent arguments are converted for output.
along with §7.21.6/4:
An optional minimum field width. If the converted value has fewer
characters than the field width, it is padded with spaces (by default)
on the left (or right, if the left adjustment flag, described later,
has been given) to the field width. The field width
takes the form of an asterisk * (described later) or a nonnegative decimal integer.
As you quoted "Minimum number of characters to be printed.", so "+" is just another character for printf. Btw the zeros "0" are just characters aswell and have nothing to do with numbers. It could be any character.
Yes, the field width refers to the complete, converted value including decimal dots, signs etc.
You asked for a 3 characters length format and get 3 characters +57. If you want the 0 to be present, just use printf("[%+04ld]", t); and you'll get +057.

Formatting floating point numbers in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Avoid trailing zeroes in printf()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
FILE *file;
double n;
file = fopen("fp.source", "r");
while(!feof(file)) {
fscanf(file, "%lf", &n);
printf("Next double:\"%lf\"\n", n);
}
fclose(file);
return 0;
}
Hi I am trying to scan for floating point numbers and I have gotten it to work, but I get trailing zeroes that I don't want. Is there a way to avoid this? For example, the current output I get is:
Next double:"11.540000"
When in reality I would like:
Next double:"11.54"
That's not a problem with scanning. That is a problem with printf formatting.
From the documentation (emphasis mine):
f, F
The double argument shall be converted to decimal notation in the style "[-]ddd.ddd", where the number of digits after the radix character is equal to the precision specification. If the precision is missing, it shall be taken as 6; if the precision is explicitly zero and no '#' flag is present, no radix character shall appear. If a radix character appears, at least one digit appears before it. The low-order digit shall be rounded in an implementation-defined manner.
You probably want %g (again, emphasis mine):
g, G
The double argument shall be converted in the style f or e (or in the style F or E in the case of a G conversion specifier), with the precision specifying the number of significant digits. If an explicit precision is zero, it shall be taken as 1. The style used depends on the value converted; style e (or E ) shall be used only if the exponent resulting from such a conversion is less than -4 or greater than or equal to the precision. Trailing zeros shall be removed from the fractional portion of the result; a radix character shall appear only if it is followed by a digit or a '#' flag is present.
Is there a way to avoid this?
Yes, just format the output correctly:
printf("Next double:\"%.0lf\"\n", n);
The .0 in the printf format string indicates that you don't want to print any digits after the decimal point. You can change the 0 to some other value if you want one, two, three or more digits after the decimal.
Try this.
printf("Next double:\"%l.0f\"\n", n);
Here's a good reference for string format specifiers.
http://www.cplusplus.com/reference/cstdio/printf/

How does C Handle Integer Literals with Leading Zeros, and What About atoi?

When you create an integer with leading zeros, how does c handle it? Is it different for different versions of C?
In my case, they just seem to be dropped (but maybe that is what printf does?):
#include <stdio.h>
int main() {
int a = 005;
printf("%i\n", a);
return 0;
}
I know I can use printf to pad with 0s, but I am just wondering how this works.
Leading zeros indicate that the number is expressed in octal, or base 8; thus, 010 = 8. Adding additional leading zeros has no effect; just as you would expect in math, x + 0*8^n = x; there's no change to the value by making its representation longer.
One place you often see this is in UNIX file modes; 0755 actually means 7*8^2+5*8+5 = 493; or with umasks such as 0022 = 2*8+2 = 10.
atoi(nptr) is defined as equivalent to strtol(nptr, (char **) NULL, 10), except that it does not detect errors - as such, atoi() always uses decimal (and thus ignores leading zeros). strtol(nptr, anything, 0) does the following:
The string may begin with an arbitrary
amount of white space (as determined
by isspace(3)) followed by a single
optional '+' or '-' 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).
So it uses the same rules as the C compiler.
The fact that a leading zero indicates a number is octal is something that's often forgotten. I've seen it cause confusion several times, such as when someone tried to input an IP address using a nice, regular format for the octets:
192.168.010.073
and the parser interpreted the last 2 octets as octal numbers.
The only thing worse than C's unfortunate use of leading zeros to make a number octal is Javascript's handling of leading zeros to sometimes make a number octal (the number is octal if the rest of the digits are OK - less than 8 - decimal otherwise). In Javascript, (017 == 15) but (018 == 18).
I'd rather there be an error; actually I'd rather drop octal literal support altogether. At least use a more in-your-face prefix, like maybe
0t10 (ocTal 8)
0k17 (oKtal 15)
But I'm about 35 years too late with my proposal.
Be careful!
In this statement 005 is an octal constant.
int a = 005;
In this case it doesn't matter because a single digit octal constant has the same value as the equivalent decimal constant but in C: 015 != 15
Whether an integer literal is expressed in octal, decimal or hexadecimal, once it is parsed by the compiler it is just treated as a value. How an integer is output via printf depends only on its type, its value and the format specifiers (and the active locale).
A number with a leading zero means octal encoding in all versions of C. So 011 == 9 == 0x9.
Octal is a numbering system based on 8 (instead of 10 for decimal or 16 for hex). So 011 == 1*8 + 1, 013 == 1*8 + 3, etc.
You should try:
int a = 5;
printf("%03i\n", a);
0 means "pad with zeroes", 3 is the desired length of output.
Edit: Sorry, I've read your question too quickly - now I see you've asked about something completely different. However I'll leave this as is, as it might be helpful for someone else.
A number with leading 0 denoted that the number is an octal number. It's called Integer Literals. You can also use 0b for denoting binary number, for hexadecimal number it is 0x or 0X. You don't need to write any thing for decimal. See the code bellow.
#include<stdio.h>
int main()
{
int binary = 0b10;
int octal=010;
int decimal = 10;
int hexa = 0x10;
printf("%d %d %d %d\n", octal, decimal, hexa, binary);
}
For more information visit tutorialspoint.
Integers don't have "leading zeros" a 5 is a 5, you may write its string representation with leading 0 if you want, for that you have the printf modifiers.
In your particular case, the zeroes are being dropped by printf.
All leading zeroes are stripped out by the compiler except for the initial zero which causes your compiler to treat the integer as octal. For 005, both the octal and decimal representations are the same and should not bother you but still, it's asking for trouble unless you specifically meant the octal representation.
Leading zeroes have to do purely with the string representation of the integer. To print with leading zeroes, use "%03d". This will ensure a field length of 3.
In general, "%<x>d" will print an integer x characters wide and will pad with leading spaces. "%0<x>d" will do the same thing but will pad with leading zeroes.

Resources