This is an old revision of the document!
An attempt at sharing some of the great questions I've received with everybody.
In argv[1] the number input is an array of characters but it needs conversion to a singular octal value. Why?
As argv[1] is an array of characters… if you give it 640, it'll actually be “640\0”, that is, ASCII character '6', followed by ASCII character '4', followed by ASCII character '0', followed by the NULL terminator.
'6' has a numeric value of 54 (decimal).
If you were to convert “640” to an integer value 640, that would be 640 in base 10; 640(10) to base 8 would be: 1200
If you pass that decimal 640 to the chmod() function, you'd end up with the sticky bit being set (T in other) along with user write, and NOTHING else. Not 640 as we desire.
So, entering 640 on the command-line would not result in a direct conversion to octal 0640… some converting will be in order.
Since octal values start with a leading zero, if I insert an ASCII '0' at the start of the string and then convert it using atoi(3), wouldn't that work? It doesn't seem to be the case.
That leading zero is only a convenience, implemented on a case by case basis. It would appear atoi(3) does not implement it. Look at this:
#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int result = atoi(argv[1]); // take the first argument and convert it to an integer printf("argv[1] is \"%s\"\n", argv[1]); // display the original string, for comparison // display the result in octal, decimal, and hex printf("result is %o in octal, %d in decimal, and %x in hexadecimal\n", result, result, result); return(0); }
And look at the output:
lab46:~$ ./testatoi 640 argv[1] is "640" result is 1200 in octal, 640 in decimal, and 280 in hexadecimal lab46:~$ ./testatoi 0640 argv[1] is "0640" result is 1200 in octal, 640 in decimal, and 280 in hexadecimal
As you can see, even if you had a 0640, the leading zero would be dropped in the conversion, because atoi(3) is apparently only cognizant of decimal values (and good, because that would have taken the fun out of this particular problem… you stand to learn some important things by working through this process).
And also, do you see that regardless of displaying it in octal, decimal, or hex, it is the same value? They're all being sourced from an integer variable called result… a regular old int… so it ultimately is up to how we instruct the computer to interpret it… after all, EVERYTHING is in binary, even if we are thinking through the problem exclusively in decimal.
Why doesn't adding the leading zero make it octal?
The leading zero is a convenient way to identify an octal value. It is a means to mark one, but by no means a required form. That C and other facilities on the computer support a leading 0 for octal and a leading 0x for hex makes our lives easier, but only goes as far as support for such things has been implemented.
We do the same in language. If I were to say the following value is in base 8: 72033
You would understand because I identified it as such… note the lack of the leading zero. If I wanted to be more brief, instead of saying “the following value is in base 8” I could just prefix a 0 on, because that shortcut is generally understood (within the context of assignable values in C syntax). But it is by no means the only way to do it.