In C, I can tell printf to print the arguments in an order different than the order they are passed in:
printf("%2$d %1$d\n", 10, 20);
//prints 20 10
However, if I try to do the same in Lua I get an error:
print(string.format("%2$d %1$d\n", 10, 20))
invalid option '%$' to 'format'
Is there a way to create a Lua format string that causes string.format to write the second argument before the first? I am working with an internationalization and changing the format string is easy but changing the argument order is much more tricky.
I would have expected the technique that I used in C to work with Lua because, according to the manual, string.format should receive the same parameters as sprintf. Are %2$ directives not part of ANSI C or is the Lua manual just forgetting to mention that they are not supported?
In short, no. %2$ directives are a POSIX extension, thus not part of ANSI C or Lua. This has been brought up on the Lua mailing list before, and according to lhf, the feature was around in versions prior to Lua 5 but was removed with that version's release. In the same thread, a wiki page of alternatives was suggested.
If you really want the %2$ style, then it's not too difficult to cook up your own fix either.
local function reorder(fmt, ...)
local args, order = {...}, {}
fmt = fmt:gsub('%%(%d+)%$', function(i)
table.insert(order, args[tonumber(i)])
return '%'
end)
return string.format(fmt, table.unpack(order))
end
print(reorder('%2$d %1$d\n', 10, 20))
You cannot do this with string.format, but you can actually achieve almost the same result with string.gsub. The caveat here is that the last argument of string.gsub can be either string or table (with multiple values to replace)
So this code would do the trick:
local output = string.gsub("%2 %1 %2 %1\n", '%S+', {['%1'] = 10, ['%2'] = 20})
print(output)
> 20 10 20 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With