I'm trying to find a good way to print leading 0, such as 01001 for a ZIP Code. While the number would be stored as 1001, what is a good way to do it?
I thought of using either case statements or if to figure out how many digits the number is and then convert it to an char array with extra 0's for printing, but I can't help but think there may be a way to do this with the printf format syntax that is eluding me.
printf("%05d", zipCode);
The 0 indicates what you are padding with and the 5 shows the width of the integer number.
Example 1: If you use "%02d" (useful for dates) this would only pad zeros for numbers in the ones column. E.g., 06 instead of 6.
Example 2: "%03d" would pad 2 zeros for one number in the ones column and pad 1 zero for a number in the tens column. E.g., number 7 padded to 007 and number 17 padded to 017.
The correct solution is to store the ZIP Code in the database as a STRING. Despite the fact that it may look like a number, it isn't. It's a code, where each part has meaning.
A number is a thing you do arithmetic on. A ZIP Code is not that.
You place a zero before the minimum field width:
printf("%05d", zipcode);
sprintf(mystring, "%05d", myInt);
Here, "05" says "use 5 digits with leading zeros".
If you are on a *nix machine:
man 3 printf
This will show a manual page, similar to:
0 The value should be zero padded. For d, i, o, u, x, X, a, A, e,
E, f, F, g, and G conversions, the converted value is padded on
the left with zeros rather than blanks. If the 0 and - flags
both appear, the 0 flag is ignored. If a precision is given
with a numeric conversion (d, i, o, u, x, and X), the 0 flag is
ignored. For other conversions, the behavior is undefined.
Even though the question is for C, this page may be of aid.
ZIP Code is a highly localised field, and many countries have characters in their postcodes, e.g., UK, Canada. Therefore, in this example, you should use a string / varchar field to store it if at any point you would be shipping or getting users, customers, clients, etc. from other countries.
However, in the general case, you should use the recommended answer (printf("%05d", number);).
There are two ways to output your number with leading zeroes:
Using the 0 flag and the width specifier:
int zipcode = 123;
printf("%05d\n", zipcode); // Outputs 00123
Using the precision specifier:
int zipcode = 123;
printf("%.5d\n", zipcode); // Outputs 00123
The difference between these is the handling of negative numbers:
printf("%05d\n", -123); // Outputs -0123 (pad to 5 characters)
printf("%.5d\n", -123); // Outputs -00123 (pad to 5 digits)
ZIP Codes are unlikely to be negative, so it should not matter.
Note however that ZIP Codes may actually contain letters and dashes, so they should be stored as strings. Including the leading zeroes in the string is straightforward so it solves your problem in a much simpler way.
Note that in both examples above, the 5 width or precision values can be specified as an int argument:
int width = 5;
printf("%0*d\n", width, 123); // Outputs 00123
printf("%.*d\n", width, 123); // Outputs 00123
There is one more trick to know: a precision of 0 causes no output for the value 0:
printf("|%0d|%0d|\n", 0, 1); // Outputs |0|1|
printf("|%.0d|%.0d|\n", 0, 1); // Outputs ||1|
printf allows various formatting options.
Example:
printf("leading zeros %05d", 123);
You will save yourself a heap of trouble (long term) if you store a ZIP Code as a character string, which it is, rather than a number, which it is not.
More flexible..
Here's an example printing rows of right-justified numbers with fixed widths, and space-padding.
//---- Header
std::string getFmt ( int wid, long val )
{
char buf[64];
sprintf ( buf, "% *ld", wid, val );
return buf;
}
#define FMT (getFmt(8,x).c_str())
//---- Put to use
printf ( " COUNT USED FREE\n" );
printf ( "A: %s %s %s\n", FMT(C[0]), FMT(U[0]), FMT(F[0]) );
printf ( "B: %s %s %s\n", FMT(C[1]), FMT(U[1]), FMT(F[1]) );
printf ( "C: %s %s %s\n", FMT(C[2]), FMT(U[2]), FMT(F[2]) );
//-------- Output
COUNT USED FREE
A: 354 148523 3283
B: 54138259 12392759 200391
C: 91239 3281 61423
The function and macro are designed so the printfs are more readable.
If you need to store the ZIP Code in a character array, zipcode[], you can use this:
snprintf(zipcode, 6, "%05.5d", atoi(zipcode));
Related
For starters, I'm new to programming
I'd like to know how to store a number with leading zeroes in it with scanf instead of modifying the printf. Is it related to data types? If so, what is it? and how do I use it? I currently only know int, double and float
For example, I'd like to input the number "02" and receive "02" as the output, and when I input "2" the output will also be "2".
how to store a number with leading zeroes (?)
I currently only know int, double and float
To store an integer and the leading zero count is then 2 pieces of information. When reading user input, record the number and its length or textual width.
" " to consume whitespace.
"%n" to record the offset of characters scanned so far. This does not affect the return value of scanf().
int num;
int n1, n2;
if (scanf(" %n%d%n", &n1, &num, &n2) != 1) {
puts("Failed to read an int");
}
Otherwise, print it.
"0": pad with zeros.
"*": minimum width to print derived from argument list.
else {
int length = n2 - n1;
printf("%0*d\n", length, num);
}
Input/output
007
007
The result of using scanf specifiers d, i, o, u, x, a, e, f, g is a mathematical number. There are no leading zeros. Conceptually, there are no digits in a number; it is a pure mathematical entity. (As Jonathan Leffler notes, leading zeros in the input matter the i specifier; a leading zero changes the base to octal while interpreting the numeral. This is for input only; the result is still a number with no associated digits or base.)
To preserve the leading zeros of a numeral, you must treat it as a string. scanf can be used to read strings or individual characters with the s, c, and [ specifiers, although you might wish to use a simple get-character function such as getchar. You would have to count the leading zeros yourself. The remaining digits could also be handled as a string, or you could convert them to a number.
If you store the number as an integer (e.g., int) or floating point type, any formatting information is inevitably lost: only the binary representation of the number is stored. (It may help to consider it as saving the idea of the number, e.g., "two", not how it looks when written.)
You need to store any additional information elsewhere, such as by saving the original string and using that for output, or by saving the number of digits and applying that to the printf format. There are also decimal number libraries that can internally save the decimal representation of the number, but that is considerably heavier than using the native types.
(Alternatively, just settle on a canonical output format and use that regardless of input. Is the goal really to preserve any input formatting as is, or would it suffice to always add the leading zeroes to the output?)
As already explained, numbers don't have leading zeros.
You can however treat it as a string
printf("Enter num: ");
char buf[50];
scanf("%s", &buf);
printf("You entered: %s", buf);
If you've got an int value, internally it's always represented as a certain number of bits (or whatever your CPU uses to store numbers) so you have no control over this.
There's always "leading zeroes" in terms of the internal format, because, for example, because 2099 is actually 0b00000000000000000000100000110011 in 32-bit form. This gets more complicated due to endian issues, but the principle still holds.
The only time leading zeroes makes sense is if you're using binary coded decimal, which has fallen out of style, or string notation such as produced by sprintf type functions.
It's only humans that care about digits. As far as a computer's concerned it's equally difficult to add 1+1 as it is 6916863870493370158+6471945999301299985 because they're both 64-bit operations.
Is there a way to specify the number of spaces using a variable?
For example lets say I have a basic print statement:
printf("%5d",someNumber);
This will print 5 spaces then the number. Is there a way that would let me declare a variable var = 5, and use a variable to determine spacing instead? The reason i'm asking is because I'm trying to control the number of spaces after each iteration of a loop to format data a certain way
Try:
printf("%*d", width, someNumber);
You can find more info by man 3 printf
"%5d" prints at least 5 characters. Leading spaces are first printed as needed, then the '-' sign, if needed, then the digits.
To print an int with at least n characters,use '*', the minimum field width:
printf("%*d", n, someNumber);
To print n spaces only, use
printf("%*s", n, "");
The format string is just that: a string. You can build your own with sprintf() e.g.:
sprintf(frmt,"%%%dd",iterator);
If iterator = 3 wil give the format string "%3d" which you can use in printf() like e.g.:
printf(frmt,some_number);
(The variable field width posted by Jesse Chen is not necessarily available everywhere)
#define FMT "%-*.*s e = %6ld, chars = %7ld, stat = %3u: %c %c %c %c\n"
This macro is passed into the printf function. What does %-*.*s mean?
You can read the manual page for printf. But it's more like a law text than a tutorial, so it will be hard to understand.
I didn't know *.* and had to read the man page myself. It's interesting. Let's start with a simple printf("%s", "abc"). It will print the string abc.
printf("%8s", "abc") will print abc, including 5 leading spaces: 8 is the "field width". Think of a table of data with column widths so that data in the same column is vertically aligned. The data is by default right-aligned, suitable for numbers.
printf("%-8s", "abc") will print abc , including 5 trailing spaces: the minus indicates left alignment in the field.
Now for the star:
printf("%-*s", 8, "abc") will print the same. The star indicates that the field width (here: 8) will be passed as a parameter to printf. That way it can be changed programmatically.
Now for the "precision", that is:
printf("%-*.10s", 8, "1234567890123") will print only 1234567890, omitting the last three characters: the "precision" is the maximum field width in case of strings. This is one of the rare cases (apart from rounding, which is also controlled by the precision value) where data is truncated by printf.
And finally
printf("%-*.*s", 8, 10, "1234567890123") will print the same as before, but the maximum field width is given as a parameter, too.
I'm working on bringing some old code from 1998 up to the 21st century. One of the first steps in the process is converting the printf statements to QString variables. No matter how many times I look back at printf though, I always end up forgetting one thing or the other. So, for fun, let's decode it together, for ole' times sake and in the process create the first little 'printf primer' for Stackoverflow.
In the code, I came across this little gem,
printf("%4u\t%016.1f\t%04X\t%02X\t%1c\t%1c\t%4s", a, b, c, d, e, f, g);
How will the variables a, b, c, d, e, f, g be formatted?
Danny is mostly right.
a. unsigned decimal, minimum 4 characters, space padded
b. floating point, minimum 16 digits before the decimal (0 padded), 1 digit after the decimal
c. hex, minimum 4 characters, 0 padded, letters are printed in upper case
d. same as above, but minimum 2 characters
e. e is assumed to be an int, converted to an unsigned char and printed
f. same as e
g. This is likely a typo, the 4 has no effect. If it were "%.4s", then a maximum of 4 characters from the string would be printed. It is interesting to note that in this case, the string does not need to be null terminated.
Edit: jj33 points out 2 errors in b and g above here.
#Jason Day, I think the 4 in the last %4s is significant if there are fewer than 4 characters. If there are more than 4 you are right, %4s and %s would be the same, but with fewer than 4 chars in g %s would be left justified and %4s would be right-justified in a 4 char field.
b is actually minimum 16 chars for the whole field, including the decimal and the single digit after the decimal I think (16 total chars vs 18 total chars)
Here's my printf primer:
http://www.pixelbeat.org/programming/gcc/format_specs.html
I always compile with -Wall with gcc which
will warn about any mismatches between the supplied
printf formats and variables.
#jj33, you're absolutely right, on both counts.
#include <stdio.h>
int main(int argc, char *argv[]) {
char *s = "Hello, World";
char *s2 = "he";
printf("4s: '%4s'\n", s);
printf(".4s: '%.4s'\n", s);
printf("4s2: '%4s'\n", s2);
printf(".4s2: '%.4s'\n", s2);
return 0;
}
$ gcc -o foo foo.c
$ ./foo
4s: 'Hello, World'
.4s: 'Hell'
4s2: ' he'
.4s2: 'he'
Good catch!
a. decimal, four significant digits
b. Not sure
c. hex, minimum 4 characters
d. Also hex, minimum 2 characters
e. 1 character
f. String of characters, minimum 4
What you really need is a tool which takes the format strings in printf() statements and converts them into equivalent QString based function calls.
Does anyone want to spend his Free Software Donation Time on developing such a tool?
Placeholder for URL to a Free Software hosting service holding the source code of such a tool
I'm trying to find a good way to print leading 0, such as 01001 for a ZIP Code. While the number would be stored as 1001, what is a good way to do it?
I thought of using either case statements or if to figure out how many digits the number is and then convert it to an char array with extra 0's for printing, but I can't help but think there may be a way to do this with the printf format syntax that is eluding me.
printf("%05d", zipCode);
The 0 indicates what you are padding with and the 5 shows the width of the integer number.
Example 1: If you use "%02d" (useful for dates) this would only pad zeros for numbers in the ones column. E.g., 06 instead of 6.
Example 2: "%03d" would pad 2 zeros for one number in the ones column and pad 1 zero for a number in the tens column. E.g., number 7 padded to 007 and number 17 padded to 017.
The correct solution is to store the ZIP Code in the database as a STRING. Despite the fact that it may look like a number, it isn't. It's a code, where each part has meaning.
A number is a thing you do arithmetic on. A ZIP Code is not that.
You place a zero before the minimum field width:
printf("%05d", zipcode);
sprintf(mystring, "%05d", myInt);
Here, "05" says "use 5 digits with leading zeros".
If you are on a *nix machine:
man 3 printf
This will show a manual page, similar to:
0 The value should be zero padded. For d, i, o, u, x, X, a, A, e,
E, f, F, g, and G conversions, the converted value is padded on
the left with zeros rather than blanks. If the 0 and - flags
both appear, the 0 flag is ignored. If a precision is given
with a numeric conversion (d, i, o, u, x, and X), the 0 flag is
ignored. For other conversions, the behavior is undefined.
Even though the question is for C, this page may be of aid.
ZIP Code is a highly localised field, and many countries have characters in their postcodes, e.g., UK, Canada. Therefore, in this example, you should use a string / varchar field to store it if at any point you would be shipping or getting users, customers, clients, etc. from other countries.
However, in the general case, you should use the recommended answer (printf("%05d", number);).
There are two ways to output your number with leading zeroes:
Using the 0 flag and the width specifier:
int zipcode = 123;
printf("%05d\n", zipcode); // Outputs 00123
Using the precision specifier:
int zipcode = 123;
printf("%.5d\n", zipcode); // Outputs 00123
The difference between these is the handling of negative numbers:
printf("%05d\n", -123); // Outputs -0123 (pad to 5 characters)
printf("%.5d\n", -123); // Outputs -00123 (pad to 5 digits)
ZIP Codes are unlikely to be negative, so it should not matter.
Note however that ZIP Codes may actually contain letters and dashes, so they should be stored as strings. Including the leading zeroes in the string is straightforward so it solves your problem in a much simpler way.
Note that in both examples above, the 5 width or precision values can be specified as an int argument:
int width = 5;
printf("%0*d\n", width, 123); // Outputs 00123
printf("%.*d\n", width, 123); // Outputs 00123
There is one more trick to know: a precision of 0 causes no output for the value 0:
printf("|%0d|%0d|\n", 0, 1); // Outputs |0|1|
printf("|%.0d|%.0d|\n", 0, 1); // Outputs ||1|
printf allows various formatting options.
Example:
printf("leading zeros %05d", 123);
You will save yourself a heap of trouble (long term) if you store a ZIP Code as a character string, which it is, rather than a number, which it is not.
More flexible..
Here's an example printing rows of right-justified numbers with fixed widths, and space-padding.
//---- Header
std::string getFmt ( int wid, long val )
{
char buf[64];
sprintf ( buf, "% *ld", wid, val );
return buf;
}
#define FMT (getFmt(8,x).c_str())
//---- Put to use
printf ( " COUNT USED FREE\n" );
printf ( "A: %s %s %s\n", FMT(C[0]), FMT(U[0]), FMT(F[0]) );
printf ( "B: %s %s %s\n", FMT(C[1]), FMT(U[1]), FMT(F[1]) );
printf ( "C: %s %s %s\n", FMT(C[2]), FMT(U[2]), FMT(F[2]) );
//-------- Output
COUNT USED FREE
A: 354 148523 3283
B: 54138259 12392759 200391
C: 91239 3281 61423
The function and macro are designed so the printfs are more readable.
If you need to store the ZIP Code in a character array, zipcode[], you can use this:
snprintf(zipcode, 6, "%05.5d", atoi(zipcode));