C/C++ printf Type Functions
Posted: Tue Jan 17, 2012 2:27 pm
I'm writing this tutorial because there appears to be confusion and misunderstanding of how to use functions like printf, sprintf, fprintf, vsprintf, etc. As of right now, I'm only going to cover what EQ2Emu related types should be used with the printf formatting specifiers because anything else about printf you can read in online tutorials like these good ones:
http://www.cplusplus.com/reference/clib ... io/printf/
http://pubs.opengroup.org/onlinepubs/00 ... rintf.html
http://www.codingunit.com/printf-format ... ted-output
int8, sint8, int16, sint16, sint32
If you're trying to print the numerical value of these, you're going to use %i or %d. %i and %d do exactly the same thing - I have no idea why there are 2. I typically like to use %i because I relate it to integer. %i or %d prints SIGNED integers. This is why it is unsafe to print an int32 (unsigned integer) using %i.
Now, if you have an int8 or sint8 and would like to print the character value of this, you can use %c. This is because an int8 is just an unsigned char, and a sint8 is just a signed char. These all have ASCII values and map to characters which can be printed instead of the ASCII value. Note: any ASCII value over 127 should not be printed as they are extended ASCII (used for non-english keyboards and other good stuff like the FAA
) and are not standard.
Example:
int32
Use %u for an unsigned integer.
int64, sint64
Use %lli and %llu for these respectively. The l stands for long, so the ll stands for long long. This one is tricky because on 32 bit architectures a long int is 4 bytes. On 64 bit architecture a long int is 8bytes. So to be safe, you can always give it a bigger specifier than needed.
const char *, char *, std::string.c_str()
%s. Notice %s takes a pointer. This can be very dangerous because what is a pointer? It's a type of unsigned integer. A pointer is just an integer that points to a memory address (NULL is a macro for 0, which points to memory location 0, which is invalid, which is why programs crash when it tries to dereference one). Therefore accidentally using an int32 in a %s is completely valid as the printf function will try to dereference memory at the location of whatever value is in that int32 and this typically does not end well.
If anyone is unclear with what I said (I tend to do that), let me know and I'll try to explain further and more in-depth.
http://www.cplusplus.com/reference/clib ... io/printf/
http://pubs.opengroup.org/onlinepubs/00 ... rintf.html
http://www.codingunit.com/printf-format ... ted-output
int8, sint8, int16, sint16, sint32
If you're trying to print the numerical value of these, you're going to use %i or %d. %i and %d do exactly the same thing - I have no idea why there are 2. I typically like to use %i because I relate it to integer. %i or %d prints SIGNED integers. This is why it is unsafe to print an int32 (unsigned integer) using %i.
Now, if you have an int8 or sint8 and would like to print the character value of this, you can use %c. This is because an int8 is just an unsigned char, and a sint8 is just a signed char. These all have ASCII values and map to characters which can be printed instead of the ASCII value. Note: any ASCII value over 127 should not be printed as they are extended ASCII (used for non-english keyboards and other good stuff like the FAA
Example:
Code: Select all
int8 i = 83; //this is just like saying unsigned char i = 83;
char c = 'S'; //this is just like saying sint8 c = 'S';
printf("%c - %c\n", i, c) ==> "S - S"
printf("%i - %i\n, i, c) ==> "83 - 83"Use %u for an unsigned integer.
int64, sint64
Use %lli and %llu for these respectively. The l stands for long, so the ll stands for long long. This one is tricky because on 32 bit architectures a long int is 4 bytes. On 64 bit architecture a long int is 8bytes. So to be safe, you can always give it a bigger specifier than needed.
const char *, char *, std::string.c_str()
%s. Notice %s takes a pointer. This can be very dangerous because what is a pointer? It's a type of unsigned integer. A pointer is just an integer that points to a memory address (NULL is a macro for 0, which points to memory location 0, which is invalid, which is why programs crash when it tries to dereference one). Therefore accidentally using an int32 in a %s is completely valid as the printf function will try to dereference memory at the location of whatever value is in that int32 and this typically does not end well.
If anyone is unclear with what I said (I tend to do that), let me know and I'll try to explain further and more in-depth.