All pastes #738583 Raw Edit

variable parameter functions

public text v1 · immutable
·published 2007-10-16 14:04 UTC
rendered paste body
Variable parameter functions.

Variable parameter functions are ones which do not take a set number of parameters.  This fact is represented by the elipsis operator (...) in the function header.  The most common variable parameter functions in PAWN are the native functions printf and format, however there are other native ones and many custom ones.

format, printf and Text_SendFormat

These functions all create a string from other data, i.e. numbers and other strings, the difference is that printf displays this generated string in the server console, format saves the generated string in another string, Text_SendFormat sends the string to players for display.  These functions all use the same method of determining the types of passed parameters: the format string.  An example of this is:

"Hello %s, the number is: %d"

% is the format identifer, it tells the system to do something special, not to display the character (to display a percent sign do: %%, all other characters not following a % and not related to it are displayed normally).

The default symbols are:

b - Binary value
c - Character
d - Integer
f - Floating point
i - Integer
s - String
x - Hex value
% - Percent sign

YSI also supports a further set of symbols in it's text system:

o - Octal value
n - Command name
p - Numerical suffix

So the above format string, in a full format function would be:

format(string, sizeof (string), "Hello %s, the number is %d", "Y_Less", 5);

If you were to them read the contents of the variable string you would see:

"Hello Y_Less, the number is 5"

Why?

The format processor reads through the format string, copying letters over to the destination string until it reaches a %.  At this point it gets the type of format parameter, as determined by the next character and, using this type, gets the next parameter after the format string.  When it reaches the second % it gets the second parameter after the format string and so on (3rd gets the 3rd, 4th 4th etc) (Note: %% does not increase the paramter counter as it doesn't use a parameter so the second % would get the first parameter if it was after the %% for example).

If you use the wrong parameter type you will get very strange values and possibly even crashes.

An example of a printf statement:

printf("The value of floatVar is %f", floatVar);

The word floatVar appears twice in that strng but they are not the same.  The first is in a string so will always read as floatVar but has no knowledge at all of the variable called floatVar (you could put: printf("The value of something is %f", floatVar); and it would do exactly the same thing (except for the name of the variable displayed, which is now "something")).  floatVar, as implied by it's name, holds a float (a non-whole number such as 3.5 or 7.0 (which is whole but in float format)), from the table above we can see that the format code for displaying a float is f so we have used %f.  The output of this line will look something like:

"The value of floatVar is 7.000000"

Now I don't know about you but I don't need to know the value of a number to the nearest millionth, it probably doesn't make much difference after a hundredth, possibly a thousandth for high accuracy things, so we can change this.  In a format string % starts it and the letter identifier ends it, this means you can add additional information if you need:

printf("The value of floatVar is %.2f", floatVar);

This line will give:

"The value of floatVar is 7.00"

Which is a much nicer number to use.  The %.2f means display a float number to 2 decimal places, %.4f would display it to 4 decimal places, %.0f would basically round it off to an integer, there would be no decimal part.

The rounding is called precision, the other paramter on floats is the width, this allows you to pad out strings to a length for display purposes, e.g:

printf("Line 1: %.2f %.2f %.2f", length[0], width[0], height[0]);
printf("Line 2: %.2f %.2f %.2f", length[1], width[1], height[1]);
printf("Line 3: %.2f %.2f %.2f", length[2], width[2], height[2]);

Now lets say length, width and height are:

length = {1.5,      798.12, 34.2   }
width  = {456.1293, 890.1,  439.565}
height = {2.0,      2.0,    2.0    }

These are all nicely lined up so you can see what goes together, however if you used the print statements above you would get:

"Line 1: 1.50 798.12 34.20"
"Line 2: 456.12 890.10 439.00"
"Line 3: 2.00 2.00 2.00"

It looks very very messy, you could adjust the spacing to line them up but you would need to adjust it for every different number.  This is where widths come in.  The longest number, including decimal point, is 6 characters in this example (remember they're trimmed to 2dp), this may be the highest they go or you may have longer numbers.  Either way you need to find the longest length or number you will have and set that as your width.  Incorporating this into the print statements gives us:

printf("Line 1: %.2f %.2f %.2f", length[0], width[0], height[0]);
printf("Line 2: %.2f %.2f %.2f", length[1], width[1], height[1]);
printf("Line 3: %.2f %.2f %.2f", length[2], width[2], height[2]);

The maximum width goes before the decimal point in the float format identifier to identfy it as a width, not a precision (if you didn't have a set precision you would simply have %6f which is perfectly valid).  This gives:

"Line 1: 1.50   798.12 34.20 "
"Line 2: 456.12 890.10 439.00"
"Line 3: 2.00   2.00   2.00  "

Which is obviously better lined up.  Note that if you have a numebr longer than the max width it will show the whole number which may mess up your alignment.