Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top