When I try to format a string such as '%s%s' using a line of code like so:
format('%s%s', [x]);
I get an exception because you can't have multiple '%s' without using an array with the same amount of arguments such as:
format('%s%s', [x,x]);
However, I don't know how many '%s' I will have to format and therefore I don't know how long the array would have to be. I also only want '%s' assigned to only 1 value.
Is there a way in which you can use multiple '%s' and assign them all to the same index?
As described in the documentation you can use an index specifier to identify the argument by a zero based index. The index specifier is written immediately after the % and is followed by a :.
Your example would be:
Format('%0:s%0:s', [x])
MyStr := StringReplace('%s%s', '%s', x, [rfreplaceALL]);
Related
Luas string.format is pretty straight forward, if you know what to format.
However, I stuck at writing a function which takes a wildcard-string to format, and a variable number of arguments to put into that blank string.
Example:
str = " %5s %3s %6s %6s",
val = {"ttyS1", "232", "9600", "230400"}
Formatting that by hand is pretty easy:
string.format( str, val[1], val[2], val[3], val[4] )
Which is the same as:
string.format(" %5s %3s %6s %6s", "ttyS1, "232", "9600","230400")
But what if I wan't to have a fifth or sixth argument?
For example:
string.format(" %1s %2s %3s %4s %5s %6s %7s %", ... )
How can I implement a string.format with an variable number of arguments?
I want to avoid appending the values one by one because of performance issues.
The application runs on embedded MCUs.
Generate arbitrary number of repeats of whatever format you want with string.rep if format is the same for all arguments. Or fill table with all formats and use table.concat. Remember that you don't need to specify index of argument in format if you don't want to reorder them.
If you just need to concatenate strings together separated by space, use more suitable tool: table.concat(table_of_strings, ' ').
You can create a table using varargs:
function foo(fmt, ...)
local t = {...}
return t[6] -- might be nil
end
Ps, don't use # on the table if you expect the argument list might contain nil. Instead use select("#", ...).
I have a string
String :='this is my string | yes';
I need delphi to get whatever the text is after the |
So something like:
getTextAftertoCharacter('|',String);
This should return "yes" in the example above.
Has Delphi get a function for this?
I'm not aware of a single function that does this. I think the easiest way would be to use Pos and then Copy:
answer := Copy(str, Pos('|', str) + 1, Length(str));
Start character is at Pos('|', str) + 1, amount of characters to copy is actually Length(str)-Pos('|', str), but passing a greater value to Copy also works.
Note: this will return the whole contents of str if there is no '|'. Check for Pos('|', str) being non-zero if you need different behavior.
You can use Controls.GetLongHint():
GetLongHint(String);
That's because the separator of a two part hint is a |. In your example it would return ' yes', with the leading space. If | is not found, the function returns the String.
I'd use then following code:
Trim(RightStr(Text, Length(Text)-LastDelimiter('|', Text)));
It'll locate the last delimiter in the string and I used Trim to get rid of the whitespace. LastDelimiter can take more than one delimiter which may be usefull. If no delimiter is found it will return the whole string.
Is it possible somehow to retrieve variable value by its name (name represented as string)?
% we are calling foo function as foo(3)
foo(Param) ->
Var1 = Param * 2,
% some magic code here which can evaluate
% "Var1" string to Var1's value (6)
ok.
I want to implement (if it is possible) some kind of logger macro, like
Param = 3*4,
% This should write "My parameter value is 12" to log
?LOG("My parameter value is $Param").
Thanks.
The common way to log is to have formatting string and list of parameters. However your idea is achievable through usage of parse transform.
Thanks to Dmitry Belyaev for mentioning parse transform.
Say we have logging code:
?dump("My parameter value is $Param")
What I need here is to parse variables within format string ("My parameter value is $Param") with some regular expression. This format string contains single var name (Param). And we need to insert io_lib:format function call (by transforming original AST) with modified format string:
print_message(io_lib:format("My parameter value is ~p~n", [Param]))
In result we can archive required behavior:
Bar = "hello",
Buzz = buzz123,
?dump("Say $Bar to $Buzz"),
% => example:19: Say "hello" to buzz123
You can look at my implementation here
For toy problems you could use:
io:format("My parameter value is ~p~n", [Param]).
See io_lib and io.
Alternatively:
error_logger:info_report/1
or other error_logger functions.
The logging library lager is commonly used.
I'm trying to use LiveBindings to format a number for display in a TEdit on a FireMonkey form.
I'm trying to use the Format method in the CustomFormat of the binding to format the number with two decimal places.
I can 'hard code' the output:
Format("Hello", %s)
which is working, but I can't work out what formatting string to use. If I try a standard formatting string such as,
Format("%.2f", %s)
I get a runtime error "Format invalid or incompatible with argument".
Indeed I get an error whenever I include a % symbol in the format string, so I'm guessing Format takes a different type of argument, but I can't find any documentation to say what the correct format string is.
You can not use Format('%.2f',[%s]) in LiveBindings -> CustomFormat
The %s is reserved for the data and for a TEdit , it's a string
d : double;
s : string;
...
d := 1234.5678;
s:=Format('%.2f',[d]);
Format() is to convert [int, decimal, double, float] to a string .
all other give you a error : invalid argument
valid is for example
TLinkControlToField1 -> CustomFormat : "Double : "+UpperCase(%s)
will give you in Edit1.text
Double : 1234.5678
OK , we know that Uppercase() for '1234.5678' has no effects .
Is only to show (%s) is a string
Solutions:
Set to TFloatField -> DisplayFormat #00000.00
rounds and display 01234.57
check TFloatField -> currency
rounds and display 1234.57
use a component look here
LiveBindings in XE3: Formatting your Fields
The parameter is passed into CustomFormat as %s. The bindings system preparses out this parameter before the data is passed onto the evaluator. Thus any other % symbols in the CustomFormat string will give an error.
As with a normal format string you can include a literal % sign by putting a double % (i.e. %%).
So, any %s in the format string need to be converted to %%, e.g.
Format('%%.2f', %s)
which gets parsed out to
Format('%.2f', 67.66666)
and then parsed down to
67.67
for display.
If you want to include a literal % in the final output you need to put a quadrupal %, e.g.
Format('%%.2f%%%%', %s)
becomes
Format('%.2f%%', 67.6666)
and displays as
67.67%
Note: The normal format function takes a final parameter which is an array of values. The Format method in the bindings system takes a variable length list of parameters.
Also, the method names are case sensitive. 'Format' is correct, 'format' will fail.
imput 67.6666
CUSTOM FORMAT: ToStr(Format('%%.2f', Value)) + ' %%'
output 67.00 %
I want to update a text like "Updating report (1 0f 5)". I thought format function will help me to do that. I want something like this
string := Format('Updating report ( %d of %d, [1], [2])', loop, count );
but it is not possible. I have an option to have loop and count stored in a string and concatenate everything. But is there any other way to achieve what i want?
Your syntax is wrong. The second parameter to the Format is an open array containing the arguments. So you need to wrap your list of arguments in what is known as an open array constructor.
An open array constructor is a sequence of expressions separated by commas and enclosed in brackets.
So, write the code like this:
str := Format('Updating report (%d of %d)', [loop, count]);