C printf %d incorrect value with leading zeros? [duplicate] - c

This question already has an answer here:
Strange behavior in C when calculating sum of digits with leading zeroes
(1 answer)
Closed 5 years ago.
The C function printf seems to print different values depending on whether or not leading zeros are present.
I was trying to determine the numerical values for the mode argument in the Linux 'open' system call.
printf("mode:%d\n",S_IRWXU);
printf("mode:%d\n",00700);
both gave me 448, while
printf("mode:%d\n",700); gives me 700, as I would expect from both.
What is going on here?
I am using gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609

A numerical constant with one or more leading zeros is an octal constant, while one without a leading zero is a decimal constant and one with a leading 0x is a hexadecimal constant. This holds in any context, whether the value is passed to printf or any other function.
In the case of printf, you're using the %d format specifier which prints the value in decimal. If you pass in an octal constant, you'll see the decimal value of that octal number. In this example, 0700b8 == 7 * 8^2 + 0 * 8^1 + 0 * 8^0 == 7 * 64 == 448b10
If you're dealing with file permissions, those values are typically denoted as octal, so you should always use a leading 0 with those.

Related

C Programming: Does Modulus Ignore Leading Zeros in Result ? How Can I Stop It? [duplicate]

This question already has answers here:
Printing leading 0's in C
(11 answers)
keeping leading zeros in C [duplicate]
(3 answers)
Closed 5 years ago.
I'm programming a microcontroller in C and since the compiler or chip doesn't handle Floating Point numbers very well, it is recommended to scale the floating point value up enough to get rid of the decimal and then when outputting the number, scale it back down with a proportional division and use modulus to find and display the fractional part. Here's an example:
Start with number 25.0625. Multiply by 10000 to get 250625. Good now we don't have a float anymore. Now to display this we use a line like this:
sprintf(buffer, "%li.%i", Temp / 10000, abs(Temp % 10000));
So we first get the 25 back out by / 10000, then we get the 0625 out by % 10000. Here's the problem though: It appears my modulus result ignores the leading zero in 0625 so when it concatenates the number back together, it becomes 25.625 instead of 25.0625. I can't count on there always being a leading zero, so stuffing a zero in there isn't the answer, and there could at other times be several leading zeros. My question is, how do I suppress the modulus from excluding leading zeros ? Thanks.
You can tell sprintf to format the number in a 4-digit field with leading zeroes.
sprintf(buffer, "%li.%04d", Temp / 10000, abs(Temp % 10000));
See Printing leading 0's in C?

What the hash sign do in the following statement [duplicate]

This question already has answers here:
How # flag in printf works?
(3 answers)
Closed 7 years ago.
Can someone explain what the purpose of the # sign in this printf statement:
printf("%#d\n",15);
It seems to be ignored while printing. The output of the statement is:
15
You can look in the printf documentation. You can find the description for # under flags:
Used with o, x or X specifiers the value is preceded with 0, 0x or 0X
respectively for values different than zero. Used with e, E and f, it
forces the written output to contain a decimal point even if no digits
would follow. By default, if no digits follow, no decimal point is
written. Used with g or G the result is the same as with e or E but
trailing zeros are not removed.
I didn't come up with this answer myself. I just did a quick Google search and found this:
"Adding a # will cause a '0' to be prepended to an octal number (when using the o conversion specifier), or a 0x to be prepended to a hexadecimal number (when using a x conversion specifier). For most other conversion specifiers, adding a # will simply force the inclusion of a decimal point, even if the number has no fractional part."
You can read more here:
http://www.cprogramming.com/tutorial/printf-format-strings.html

When displaying the value of variable "int a = 011", I get 9. Why? [duplicate]

This question already has answers here:
What does it mean when a numeric constant in C/C++ is prefixed with a 0?
(7 answers)
printf with "%d" of numbers starting with 0 (ex "0102") giving unexpected answer (ex '"66")
(4 answers)
Closed 7 years ago.
With this code snippet:
int a = 011;
printf("a = %d", a);
Why is the result
a = 9
011 is an octal value and its decimal equivalent is 9. Preceding integer literal with 0 indicates octal value.
Use %o specifier in printf to print the value in octal.
A leading 0, in an int literal or int constant, represents the octal value. It is called an octal constant.
Related: C11 standard, chapter 6.4.4.1, Integer constants, Paragraph 3,
An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only.
With 0 at the beginning of of a numeric literal, you specify the octal system. And 11 in the octal system is 1*8 + 1 = 9.

Why the answer of "printf("%d", '0/');" is 12335? [duplicate]

This question already has answers here:
Multiple characters in a character constant
(3 answers)
Closed 8 years ago.
This is the c code:
int main(int argc, const char *argv[])
{
printf("%d", '0/');
return 0;
}
The output is 12335! Then I try to replace '0/' with '00' and '000', and the outputs change to 12336 and 3158064, while 12336=48*(1+2^8), 3158064=48*(1+2^8+2^16). However, I still don't know why. What happens when '0/' is transformed to an integer for output?
PS: My computer is MBP, and the operating system is OS X 10.9.5 (13F34). The compiler is Apple LLVM 6.0.
You have constructed a "multi-character literal". The behaviour is implementation-defined, but in your case, the integer value is constructed from the ASCII values (12235 == 48 * 256 + 47).
'0/' is a multi-character constant, which means it has an implementation-defined value. In your case, the ASCII value of the characters is 0x30 0x2f. These are combined into 0x302f, which equals 12335.
Because 0/ is a multi-character constant of type int. You initialize the first part of a 2x3 buffer with it, and pass it to printf to be re-interpreted as an int, the first byte '0' is multiplied by 256 and then the second byte '/' is added to it. This produces the value that you see:
printf("%d %d %d", '0', '/', '0'*256+'/');
prints
48 47 12335
demo.
Note that this behavior is system-dependent. On other systems you could see 12080 instead of 12335.
See this answer for more information on multicharacter constants.

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