408

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.

Neuron
  • 5,141
  • 5
  • 38
  • 59
zxcv
  • 7,391
  • 8
  • 34
  • 30
  • what about this https://stackoverflow.com/questions/530614/print-leading-zeros-with-c-output-operator/71541766#71541766 – A P Mar 19 '22 at 20:25
  • @AviPars: you are suggesting a c++ solution: `std::cout << std::setw(5) << std::setfill('0') << zipCode << std::endl;` which is a typesafe but vastly overworked alternative to `printf("%05\n", (int)zipCode);` – chqrlie Mar 19 '22 at 22:01
  • No, i was suggesting to do it manually with the ascii character '0' and a conditional statement – A P Mar 20 '22 at 10:17
  • @AviPars: sorry I misread the link. This manual approach is fine for a 2 digit number, but for a 5 digit zipCode, handling all possibilities requires more code unless you can assume zipCode to be a valid USA ZIP code which starts at [`01001`](https://codigo-postal.co/en-us/usa/zip/01001/) – chqrlie Mar 20 '22 at 10:30
  • 1
    @chqrlie that's why i didnt submit it as an answer - but its nice for people to know that there are different ways of handling problems that are all valid – A P Mar 20 '22 at 10:41

11 Answers11

676
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.

EvilTeach
  • 28,120
  • 21
  • 85
  • 141
  • 280
    Please do not store zipcodes as numbers. Some countries have letters in their zipcode. – Sec Sep 30 '08 at 16:57
  • 1
    For your case, this would suffice. How can one have leading zeroes in an integer of unknown length ? – Dominic Motuka May 10 '18 at 14:58
  • 3
    You need to know the maximum length of the final padded string. Alternatively, if you always wanted 5 leading zeros, then "00000" + integer.to_s. etc – mlambie Mar 04 '20 at 05:21
176

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
James Curran
  • 101,701
  • 37
  • 181
  • 258
  • 34
    Ya. Your observation is absolutely correct. That is what I do. However the person asking the question is probably trying to deal with homework, instead of production code. The answer needs to be tailored to the person asking the question. – EvilTeach Sep 30 '08 at 17:32
  • 18
    I suppose I should have rephrased it more precisely to illustrate I was looking to see how I can do leading and trailing characters in a language I wasn't familiar with. I'll be more careful with arbitrary examples in the future! – zxcv Sep 30 '08 at 23:31
  • 3
    Other countries, like U.K. have letters in zip codes – jjxtra Sep 06 '16 at 21:21
48

You place a zero before the minimum field width:

printf("%05d", zipcode);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Adam Bellaire
  • 108,003
  • 19
  • 148
  • 163
17
sprintf(mystring, "%05d", myInt);

Here, "05" says "use 5 digits with leading zeros".

Unihedron
  • 10,902
  • 13
  • 62
  • 72
Dan Hewett
  • 2,200
  • 1
  • 14
  • 18
16

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Paul Tomblin
  • 179,021
  • 58
  • 319
  • 408
  • 1
    why is the 3 number needed ? – eri0o Feb 25 '18 at 14:47
  • 4
    @Elric If you give a numeric argument to the `man` command, it narrows it down to that particular section. Without it, you'll get the man page for the shell command `printf` instead of the C function. – Paul Tomblin Feb 25 '18 at 16:51
16

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);).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JeeBee
  • 17,476
  • 5
  • 50
  • 60
13

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|
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
chqrlie
  • 131,814
  • 10
  • 121
  • 189
6

printf allows various formatting options.

Example:

printf("leading zeros %05d", 123);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Trent
  • 13,249
  • 4
  • 39
  • 36
2

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
pro3carp3
  • 807
  • 2
  • 7
  • 17
  • If only someone would explain how to zero-pad a char array. There is even a solution that uses atoi() to turn the char array to an init and then use %05d. Hope this is not the only solution. – Niko Jan 15 '19 at 15:31
  • @Niko Well I guess you'd use `memcpy` and so on to zero-pad a char array. But why on earth would you want to do that? – Lorraine Feb 18 '21 at 09:19
0

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.

rch
  • 9
  • 1
  • 4
    I'm not 100% sure of your intention with the macro, but it looks like you meant to define a function, like `#define FMT(x) (getFmt(8,x).c_str())` (note the *x* parameter!), as opposed to a variable (which is what your code does). – Ponkadoodle Aug 02 '14 at 03:47
  • Dear @rch, the question was asked from c right..? but you provided c++ code.. Also for the good practice, you need to use less number of instructions and less amount of memory usage. – purushothaman poovai Apr 21 '22 at 06:23
0

If you need to store the ZIP Code in a character array, zipcode[], you can use this:

snprintf(zipcode, 6, "%05.5d", atoi(zipcode));
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131