A bug with String(format:) "n$" positional specifier?

Hi, please see the following code:

import Foundation

let s = String(format: "%1$@ %3$@", "Hello", "Bye", "World")
print(s)

It outputs Hello Bye, but I expected it output Hello World. I tested it with latest version of macOS and Xcode.

Apple's doc refers to IEEE printf specification about "n$" feature. The spec didn't talk about what's the expected behavior in above case. So I tested the following code on Linux:

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("%1$s %3$s", "Hello", "Bye", "World");
    exit(0);
}

It gave a warning and output Hello World (the result expected by me):

format argument 2 unused before used argument 3 in $-style format

So I think this is a bug?

Background: I'm using String(format:) to generate localized text. Due to the difference between languages, in language A I need all parameters to generate the text, but in language B I only need some of the parameters. As a result, language B's format string doesn't access all parameters and hence exposes the issue.

I wonder if anyone ran into the issue before and how do you work around it? It seems what I'm looking for is a way to reference the unused parameter in language B's format string but doesn't actually show it in the final result. Perhaps a format specifier to show 0 characters of a string?

Thanks for any suggestion.

Unfortunately the approach works in C but not in Swift.

C example (it works):

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("%1$s %3$s%2$.0s", "Hello", "Bye", "World");
    exit(0);
}

Note the %2$.0s hack. Also note that it's just to show the hack works. We don't really need the hack in C because the the original code just works fine.

Swift example (not working):

import Foundation

let s = String(format: "%1$@   %3$@%2$.0@", "Hello", "Bye", "World")
print(s)
1 Like

@xwu Thanks for the information. So a simple workaround is to call sprintf() in Swift. Unfortunately, it turns out not easy to do that. See my another question.