format() function

Started by KAKAN, Sep 29, 2015, 06:56 PM

Previous topic - Next topic

KAKAN

So, the topic says all.
I need a brief description on how to use the format() function
I have seen it in many things, mostly Gettime functions. Idk what it is used for, can anyone say it?
oh no

.

#1
It is the equivalent of the printf function found in C/C++ except it only provides a small subset of the printf function and instead of printing it's returning the string.

Consider the following variables:
local a = 3;
local b = 2;
local c = a + b;

And how you'd normally generate a string with them:
local str = "If you take" + a + " and add it to " + b + " you should get " + c;
That would generate:
If you take 3 and add it to 2 you should get 5
Well, the same can be done with:
local str = format("If you take %d and add it to %d you should get %d", a, b, c);
Except the first one is much more annoying and easy to forget a '+' which can throw an error.

So... how does the formatting work? Well, you have these format specifiers that allows you to insert certain values in a string.

Squirrel supports the following specifiers:
  • 's' String of characters
  • 'i' and 'd' Signed decimal integer
  • 'u' Unsigned decimal integer
  • 'o' Unsigned octal
  • 'x' Unsigned hexadecimal integer
  • 'X' Unsigned hexadecimal integer (uppercase)
  • 'c' Character
  • 'f'    Decimal floating point, lowercase
  • 'g' Use the shortest representation: %e or %f
  • 'G' Use the shortest representation: %E or %F
  • 'e' Scientific notation (mantissa/exponent), lowercase
  • 'E' Scientific notation (mantissa/exponent), uppercase

All those format specifiers that are prefixed with the '%' percent symbol, will represent an argument from the function. For example, if you have 2 of those in a string, then you need to pass 2 arguments to the format function.

Imagine the following format string "this %d and this is %f while %s". It expects 3 arguments to the format function, the first one is an integer 'd' the second one is a floating point 'f' and the third one is a string 's'. And the values from the arguments you pass will be inserted where those specifiers were found.

To see this in code:
local str = format("this %d and this is %f while %s", 23, 1.9, "jumping");
  • '%d' would be replaced by 23 (the first argument)
  • '%f' will be replaced by 1.9 (the second argument)
  • '%s' will be replaced by "jumping" (the third argument)

Therefore, the variable 'str' will contain "this 23 and this is 1.9 while jumping". Certainly much cleaner then a bunch of '+' string concatenation.

Now to the good stuff that you can't do so easily with '+' concatenation. Width specifiers. What I mean is that some of those specifiers can take a certain width to print. And they will either slice the passed value or pad with 0s to meet the requirements.

Let's take the following variables containing some strings:
local a = "wakazoo";
local b = "jimbocrap";
local c = "pie";

And the following format string "I found some %.4s and some %.3s with %.6s" If you look closely at the string specifier it has something extra now. It's no longer just '%s' It has a dot and a number between now. That's the width specifier. It tells how many characters you want from the passed argument.

  • variable 'a' contains "wakazoo" which has 7 characters. and since we pass it as the first argument,  which only takes 4 characters. It will slice the string to contain only "waka"
  • variable 'b' contains "jimbocrap" which has 9 characters. and since we pass it as the second argument,  which only takes 3 characters. It will slice the string to contain only "jim"
  • variable 'c' contains "pie" which has 3 characters. and since we pass it as the third argument,  which takes 6 characters. It will notice that "jim" is only 3 characters and will print just those ignoring the remaining 3 which is what the width specifier required

Therefore, the resulting string should be "I found some waka and some jim with pie".

The same applies with numbers. But unlike strings, which simply ignored the required width if it was bigger than the passed argument. Numbers will be padded with 0s.

Let's take the following variables:
local a = 182;
local b = 9;
local c = 88997755;

And the following format string "My result was %.5d including %.6d and %.3d".

  • variable 'a' contains 182 which is only 3 digits long. and we pass that as the first argument which expects 5 digits. therefore it should notice that it needs 2 more numbers. which means it will pad with 0s and get 00182
  • variable 'b' contains 9 which is only 1 digit long. and we pass that as the second argument which expects 6 digits. therefore it should notice that it needs 5 more digits. which means it will pad with 0s and get 000009
  • variable 'c' contains 88997755 which is 8 digits long. and we pass that as the third argumnet which expects 3 digits. therefore it should notice that it has 2 extra digits. now you might expect it to slice the extra digits. but it wont. it will print the whole number. unlike the string. which means you should get the whole number 88997755

Therefore, the resulting string should be "My result was 00182 including 000009 and 88997755".

There's also the '%c' specifier. Which allows you to convert a number from the ASCII table to the actual character. Currently this is the only way to get characters to strings.

Example:
local str = format("%c%c%c", 33, 66, 'A');
It should generate "!BA" 33 is the decimal identifier for '!' 66 is the decimal identifier for 'B' and for the third argument we ask squirrel to convert 'A' to it's decimal identifier which is 65.

If you try to do the same with '+' concatenation:
local str = "" + 33 + 66 + 'A';
You will get a string of "336665" because it concatenated the numbers directly into a string instead of converting them to their ASCII character.

Feel free to experiment with the remaining specifiers.
.

Thijn

Just like to add to S.L.C.'s post that in order to print the actual "%" character you'd need to escape it by prepending another % to it like so: %%