Difference between revisions of "Format Class Functions (SourceMod Scripting)"

From AlliedModders Wiki
Jump to: navigation, search
(Making your function Format-Class)
 
(9 intermediate revisions by 6 users not shown)
Line 2: Line 2:
 
Format-class functions are variable argument functions in [[SourceMod]] which allow you to format a string.  A simple example of this is the <tt>Format()</tt> function, which looks like:
 
Format-class functions are variable argument functions in [[SourceMod]] which allow you to format a string.  A simple example of this is the <tt>Format()</tt> function, which looks like:
  
<pawn>decl String:buffer[512];
+
<sourcepawn>char buffer[512];
Format(buffer, sizeof(buffer), "Your name is: %s", userName);</pawn>
+
Format(buffer, sizeof(buffer), "Your name is: %s", userName);</sourcepawn>
  
 
If userName contains "<tt>Mark</tt>," the contents of <tt>buffer</tt> will then be: "<tt>Your name is: Mark</tt>."  The prototype of these functions almost always contains the following parameters:
 
If userName contains "<tt>Mark</tt>," the contents of <tt>buffer</tt> will then be: "<tt>Your name is: Mark</tt>."  The prototype of these functions almost always contains the following parameters:
<pawn>const String:fmt[], {Handle,Float,_}:...</pawn>
+
<sourcepawn>const char[] fmt, any ...</sourcepawn>
  
 
For example, observe the following two natives:
 
For example, observe the following two natives:
<pawn>native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);
+
<sourcepawn>native void Format(char[] buffer, int maxlength, const char[] fmt, any ...);
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);</pawn>
+
native void PrintToClient(int client, char[] fmt, any ...);</sourcepawn>
  
 
Thus, <tt>PrintToClient</tt> is a format-class function.  It can be used exactly as shown earlier:
 
Thus, <tt>PrintToClient</tt> is a format-class function.  It can be used exactly as shown earlier:
<pawn>PrintToClient(client, "Your name is: %s", userName);</pawn>
+
<sourcepawn>PrintToClient(client, "Your name is: %s", userName);</sourcepawn>
  
 
=Format Specifiers=
 
=Format Specifiers=
Line 19: Line 19:
 
*'''Numerical'''
 
*'''Numerical'''
 
**'''d''' or '''i''': Integer number as decimal
 
**'''d''' or '''i''': Integer number as decimal
 +
**'''u''': Unsigned integer number as decimal
 
**'''b''': Binary digits in the value
 
**'''b''': Binary digits in the value
 
**'''f''': Floating-point number
 
**'''f''': Floating-point number
Line 32: Line 33:
 
=Usage=
 
=Usage=
 
Format specifiers are denoted with a <tt>'%s'</tt> symbol.  For example, to print a float, a number, and a string, you might use this code:
 
Format specifiers are denoted with a <tt>'%s'</tt> symbol.  For example, to print a float, a number, and a string, you might use this code:
<pawn>new Float:fNum = 5.0;
+
<sourcepawn>float fNum = 5.0;
new iNum = 5
+
int iNum = 5;
new String:str[] = "5"
+
char[] str = "5";
  
PrintToClient(client, "Number: %d Float: %f String: %s", iNum, fNum, str);</pawn>
+
PrintToClient(client, "Number: %d Float: %f String: %s", iNum, fNum, str);</sourcepawn>
  
 
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.
 
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.
Line 57: Line 58:
 
*'''specifier''': character specifying the data type (always required).
 
*'''specifier''': character specifying the data type (always required).
  
todo: examples
+
Example:
 +
<sourcepawn>
 +
PrintToServer("Characters: %c %c", 'a', 65);
 +
PrintToServer("Decimals: %d", 1977);
 +
PrintToServer("Preceding with blanks: %10d", 1977);
 +
PrintToServer("Preceding with zeros: %010d", 1977);
 +
PrintToServer("Some different radices: %d %x %X", 26, 26, 0x1A);
 +
PrintToServer("floats: %f %.2f", 3.1416, 3.1416);
 +
char abc[] = "abcdefg...";
 +
PrintToServer("%s %s", "The alphabet:", abc);
 +
PrintToServer("%s %c", abc[3], abc[3]);
 +
</sourcepawn>
  
 +
Output:
 +
<pre>
 +
Characters: a A
 +
Decimals: 1977
 +
Preceding with blanks:      1977
 +
Preceding with zeros: 0000001977
 +
Some different radices: 26 1a 1A
 +
floats: 3.141599 3.14
 +
The alphabet: abcdefg...
 +
defg... d
 +
</pre>
 
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.
 
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.
  
Line 64: Line 87:
  
 
Sourcemod allows you to make your function Format-class, ie. pass parameters to format string variables.
 
Sourcemod allows you to make your function Format-class, ie. pass parameters to format string variables.
Here's an example :
+
Here's an example:
  
<pawn>public formatExample(const String:myString[] , any:...)
+
<sourcepawn>public void formatExample(const char[] myString, any ...)
 
{
 
{
new String:myFormattedString[strlen(myString)+255];
+
int len = strlen(myString) + 255;
VFormat(myFormattedString, sizeof(myFormattedString), myString, 2);
+
char[] myFormattedString = new char[len];
 +
VFormat(myFormattedString, len, myString, 2);
 
 
 
PrintToServer(myFormattedString);
 
PrintToServer(myFormattedString);
}</pawn>
+
}</sourcepawn>
  
Using the parameter "any: ...", we can pass data(s) to format our string.
+
Using the parameter "any ...", we can pass data(s) to format our string.
Now, in order to replace the Format Specifiers by our data(s), we use the API "VFormat", which documentation can be found here : [http://docs.sourcemod.net/api/].
+
Now, in order to replace the Format Specifiers by our data(s), we use the API "VFormat", which documentation can be found here : [https://sm.alliedmods.net/new-api/].
  
 
The three first parameters passed in VFormat are pretty obvious since they are the as in the Format(..) API.
 
The three first parameters passed in VFormat are pretty obvious since they are the as in the Format(..) API.
  
The 4th parameter indicate the "any: ..." parameter position in your function prototype.
+
The 4th parameter indicate the "any ..." parameter position in your function prototype.
  
 
[[Category:SourceMod Scripting]]
 
[[Category:SourceMod Scripting]]

Latest revision as of 07:50, 26 March 2020

Introduction

Format-class functions are variable argument functions in SourceMod which allow you to format a string. A simple example of this is the Format() function, which looks like:

char buffer[512];
Format(buffer, sizeof(buffer), "Your name is: %s", userName);

If userName contains "Mark," the contents of buffer will then be: "Your name is: Mark." The prototype of these functions almost always contains the following parameters:

const char[] fmt, any ...

For example, observe the following two natives:

native void Format(char[] buffer, int maxlength, const char[] fmt, any ...);
native void PrintToClient(int client, char[] fmt, any ...);

Thus, PrintToClient is a format-class function. It can be used exactly as shown earlier:

PrintToClient(client, "Your name is: %s", userName);

Format Specifiers

A format specifier is a code that allows you to specify what data-type to print. The most common specifiers are:

  • Numerical
    • d or i: Integer number as decimal
    • u: Unsigned integer number as decimal
    • b: Binary digits in the value
    • f: Floating-point number
    • x or X: Hexadecimal representation of the binary value (capitalization affects hex letter casing)
  • Character(s)
    • s: String
    • t or T: Translates a phrase (explained in Translations)
    • c: Prints one character (UTF-8 compliant)
  • Special
    • L: Requires a client index; expands to 1<2><3><> where 1 is the player's name, 2 is the player's userid, and 3 is the player's Steam ID. If the client index is 0, the string will be: Console<0><Console><Console>
    • N: Requires a client index; expands to a string containing the player's name. If the client index is 0, the string will be: Console

Usage

Format specifiers are denoted with a '%s' symbol. For example, to print a float, a number, and a string, you might use this code:

float fNum = 5.0;
int iNum = 5;
char[] str = "5";
 
PrintToClient(client, "Number: %d Float: %f String: %s", iNum, fNum, str);

Note: Using the wrong data type with a specifier can be very dangerous. Always make sure you are printing as the right type. For example, specifying a string and passing a number can crash the server.

Advanced Formatting

Format specifiers have an extended syntax for controlling various aspects of how data is printed. The full syntax is: %[flags][width][.precision]specifier

Each bracketed section is an optional extension. Explanations of supported SourceMod format extensions:

  • %: Obviously, this is always required.
  • flags:
    • -: Left-justify (right-justify is set by default)
    • 0: Pads with 0s instead of spaces when needed (see width below).
  • width: Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.
  • precision:
    • For integers: specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).
    • For strings: specifies the maximum number of characters to print.
    • For floats: specifies the number of digits to be printed after the decimal point.
    • For all other types: no effect.
  • specifier: character specifying the data type (always required).

Example:

PrintToServer("Characters: %c %c", 'a', 65);
PrintToServer("Decimals: %d", 1977);
PrintToServer("Preceding with blanks: %10d", 1977);
PrintToServer("Preceding with zeros: %010d", 1977);
PrintToServer("Some different radices: %d %x %X", 26, 26, 0x1A);
PrintToServer("floats: %f %.2f", 3.1416, 3.1416);
char abc[] = "abcdefg...";
PrintToServer("%s %s", "The alphabet:", abc);
PrintToServer("%s %c", abc[3], abc[3]);

Output:

Characters: a A
Decimals: 1977
Preceding with blanks:       1977
Preceding with zeros: 0000001977
Some different radices: 26 1a 1A
floats: 3.141599 3.14
The alphabet: abcdefg...
defg... d

For more information, see printf from the C Standard Library, although not all modes are supported from C.

Making your function Format-Class

Sourcemod allows you to make your function Format-class, ie. pass parameters to format string variables. Here's an example:

public void formatExample(const char[] myString, any ...)
{
	int len = strlen(myString) + 255;
	char[] myFormattedString = new char[len];
	VFormat(myFormattedString, len, myString, 2);
 
	PrintToServer(myFormattedString);
}

Using the parameter "any ...", we can pass data(s) to format our string. Now, in order to replace the Format Specifiers by our data(s), we use the API "VFormat", which documentation can be found here : [1].

The three first parameters passed in VFormat are pretty obvious since they are the as in the Format(..) API.

The 4th parameter indicate the "any ..." parameter position in your function prototype.