Page 1 of 1

C/C++ printf Type Functions

Posted: Tue Jan 17, 2012 2:27 pm
by Scatman
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 :P) and are not standard.

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

Re: C/C++ printf Type Functions

Posted: Tue Jan 17, 2012 2:38 pm
by John Adams
That was more in depth than you have been since I met you. I AM rubbing off on you!

Re: C/C++ printf Type Functions

Posted: Tue Jan 17, 2012 10:46 pm
by Zcoretri
Awesome post Scatman!