支持的Swift String格式说明符是什么?

Cœu*_*œur 14 string string-formatting swift

在Swift中,我可以使用格式说明符格式化String:

// This will return "0.120"
String(format: "%.03f", 0.12)
Run Code Online (Sandbox Code Playgroud)

但官方文档没有提供有关支持的格式说明符的任何信息或链接,或者如何构建类似于以下内容的模板"%.03f":https://developer.apple.com/documentation/swift/string/1417691-init

它只说:

返回使用给定格式字符串作为模板初始化的String对象,其余的参数值将替换为该模板.

Cœu*_*œur 40

StringSwift中格式化的格式说明符与Objective-C NSString格式的格式说明符相同,本身与格式格式相同,CFString深埋在Apple文档的档案中(两个页面的内容相同,均来自2002年或更早版本):

但是这个文档页面本身是不完整的,例如没有提到标志,精度说明符和宽度说明符.实际上,它声称遵循IEEE printf规范(2004年第6版),它本身与ISO C标准一致.因此,这些说明符应与我们对C的说明符相同printf,并添加%@了Objective-C对象的说明符.


说明符

每个转换规范由'%'字符或字符序列"%n $"引入.

%D 是参数的索引,如:

String(format: "%2$@ %1$@", "world", "Hello")
Run Code Online (Sandbox Code Playgroud)

格式说明符

%@ Objective-C对象,打印为descriptionWithLocale返回的字符串:如果可用,或其他说明.

实际上,您也可以使用一些Swift类型,但它们必须在标准库中定义才能符合CVarArg协议,我相信它们需要支持对Objective-C对象的桥接:https://developer.apple. com/documentation/foundation/object_runtime/classes_bridged_to_swift_standard_library_value_types.

String(format: "%@", ["Hello", "world"])
Run Code Online (Sandbox Code Playgroud)

%%'%'字符.

String(format: "100%% %@", true.description)
Run Code Online (Sandbox Code Playgroud)

%d,%D有符号32位整数(int).

String(format: "from %d to %d", Int32.min, Int32.max)
Run Code Online (Sandbox Code Playgroud)

%u,%U无符号32位整数(unsigned int).

String(format: "from %u to %u", UInt32.min, UInt32.max)
Run Code Online (Sandbox Code Playgroud)

%x无符号32位整数(unsigned int),使用数字0-9和小写a-f以十六进制打印.

String(format: "from %x to %x", UInt32.min, UInt32.max)
Run Code Online (Sandbox Code Playgroud)

%X无符号32位整数(unsigned int),使用数字0-9和大写A-F以十六进制打印.

String(format: "from %X to %X", UInt32.min, UInt32.max)
Run Code Online (Sandbox Code Playgroud)

%o,%O无符号32位整数(unsigned int),以八进制打印.

String(format: "from %o to %o", UInt32.min, UInt32.max)
Run Code Online (Sandbox Code Playgroud)

%f 64位浮点数(双精度).

String(format: "from %f to %f", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

%e 64位浮点数(double),使用小写e以科学计数法打印以引入指数.

String(format: "from %F to %F", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

%E 64位浮点数(双精度数),用科学计数法打印,使用大写字母E表示指数.

String(format: "from %e to %e", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

%g 64位浮点数(double),如果指数小于-4或大于或等于精度,则以%e的样式打印,否则为%f的样式.

String(format: "from %E to %E", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

%G 64位浮点数(双精度),如果指数小于-4或大于或等于精度,则以%E的样式打印,否则为%f的样式.

String(format: "from %g to %g", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

%c 8位无符号字符(unsigned char).

String(format: "from %G to %G", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

%C 16位UTF-16代码单元(unichar).

String(format: "from %c to %c", "a".utf8.first!, "z".utf8.first!)
Run Code Online (Sandbox Code Playgroud)

%s以空值终止的8位无符号字符数组.

String(format: "from %C to %C", "?".utf16.first!, "?".utf16.first!)
Run Code Online (Sandbox Code Playgroud)

%S以16位UTF-16代码单元的空终止数组.

"Hello world".withCString {
    String(format: "%s", $0)
}
Run Code Online (Sandbox Code Playgroud)

%p Void指针(void*),以十六进制打印,数字为0-9,小写字母为a-f,前导0x.

"Hello world".withCString(encodedAs: UTF16.self) {
    String(format: "%S", $0)
}
Run Code Online (Sandbox Code Playgroud)

%64位浮点数(双精度数),用科学计数法打印,前导0x和小数点前的一个十六进制数字,使用小写p引入指数.

var hello = "world"
withUnsafePointer(to: &hello) {
    String(format: "%p", $0)
}
Run Code Online (Sandbox Code Playgroud)

%一个64位浮点数(双精度数),用科学计数法打印,在小数点前用前导0X和一个十六进制数字,用大写字母P表示指数.

String(format: "from %a to %a", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

%F 64位浮点数(双精度数),以十进制表示法打印.

String(format: "from %A to %A", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)
Run Code Online (Sandbox Code Playgroud)

'十进制转换结果的整数部分(%i,%d,%u,%f,%F,%g或%G)应使用数千个分组字符进行格式化.对于其他转换,行为未定义.使用非货币分组字符.

%USwift 4中似乎不支持该标志

- 转换结果应在字段内左对齐.如果未指定此标志,则转换是右对齐的.

String(format: "from %-12f to %-12d.", Double.leastNonzeroMagnitude, Int32.max)
Run Code Online (Sandbox Code Playgroud)

+签名转换的结果应始终以符号('+'或' - ')开头.只有在未指定此标志的情况下转换负值时,转换才应以符号开头.

String(format: "from %+f to %+d", Double.leastNonzeroMagnitude, Int32.max)
Run Code Online (Sandbox Code Playgroud)

<space>如果签名转换的第一个字符不是符号,或者签名转换不会产生任何字符,则<space>应以结果为前缀.这意味着如果出现<space>和'+'标志,则应忽略<space>标志.

String(format: "from % d to % d.", Int32.min, Int32.max)
Run Code Online (Sandbox Code Playgroud)

#指定将值转换为替代表单.对于o转换,它会增加精度(如果需要)以强制结果的第一个数字为零.对于x或X转换说明符,非零结果必须以0x(或0X)为前缀.对于a,A,e,E,f,F,g和G转换说明符,结果应始终包含基数字符,即使基数字符后面没有数字.如果没有此标志,只有在跟随数字后,才会在这些转换的结果中显示基数字符.对于g和G转换说明符,不应像通常那样从结果中删除尾随零.对于其他转换说明符,行为未定义.

String(format: "from %#a to %#x.", Double.leastNonzeroMagnitude, UInt32.max)
Run Code Online (Sandbox Code Playgroud)

0对于d,i,o,u,x,X,a,A,e,E,f,F,g和G转换说明符,前导零(跟随符号或基数的任何指示)用于填充到场宽; 没有执行空格填充.如果同时出现'0'和' - '标志,则忽略'0'标志.对于d,i,o,u,x和X转换说明符,如果指定了精度,则忽略"0"标志.如果出现"0"和""标志,则在填充零之前插入分组字符.对于其他转换,行为未定义.

String(format: "from %012f to %012d.", Double.leastNonzeroMagnitude, Int32.max)
Run Code Online (Sandbox Code Playgroud)

宽度修饰符

如果转换后的值的字节数少于字段宽度,则默认情况下应在左侧填充空格; 如果左侧调整标志(' - ')被赋予字段宽度,则应在右侧填充.字段宽度采用星号('*')或十进制整数的形式.

String(format: "from %12f to %*d.", Double.leastNonzeroMagnitude, 12, Int32.max)
Run Code Online (Sandbox Code Playgroud)

精密修饰剂

一个可选的精度,给出d,i,o,u,x和X转换说明符的最小位数; a,a,e,E,f和F转换说明符的基数字符后出现的位数; g和G转换说明符的最大有效位数; 或者从s和S转换说明符中的字符串打印的最大字节数.精度采用句点('.')的形式,后跟星号('*')或可选的十进制数字字符串,其中空数字字符串被视为零.如果精度与任何其他转换说明符一起出现,则行为未定义.

String(format: "from %.12f to %.*d.", Double.leastNonzeroMagnitude, 12, Int32.max)
Run Code Online (Sandbox Code Playgroud)

长度修饰符

h长度修饰符,指定后续的d,o,u,x或X转换说明符适用于short或unsigned short参数.

String(format: "from %hd to %hu", CShort.min, CUnsignedShort.max)
Run Code Online (Sandbox Code Playgroud)

hh Length修饰符,指定后续的d,o,u,x或X转换说明符适用于signed char或unsigned char参数.

String(format: "from %hhd to %hhu", CChar.min, CUnsignedChar.max)
Run Code Online (Sandbox Code Playgroud)

l Length修饰符,指定后续的d,o,u,x或X转换说明符适用于long或unsigned long参数.

String(format: "from %ld to %lu", CLong.min, CUnsignedLong.max)
Run Code Online (Sandbox Code Playgroud)

ll,q长度修饰符,指定后续的d,o,u,x或X转换说明符适用于long long或unsigned long long参数.

String(format: "from %lld to %llu", CLongLong.min, CUnsignedLongLong.max)
Run Code Online (Sandbox Code Playgroud)

L Length修饰符,指定后续的a,A,e,E,f,F,g或G转换说明符适用于long double参数.

我无法%O在Swift 4中传递CLongDouble参数

z长度修饰符,指定后续的d,o,u,x或X转换说明符适用于size_t.

String(format: "from %zd to %zu", size_t.min, size_t.max)
Run Code Online (Sandbox Code Playgroud)

t长度修饰符,指定后续的d,o,u,x或X转换说明符适用于ptrdiff_t.

String(format: "from %td to %tu", ptrdiff_t.min, ptrdiff_t.max)
Run Code Online (Sandbox Code Playgroud)

j长度修饰符,指定后续的d,o,u,x或X转换说明符适用于intmax_t或uintmax_t参数.

String(format: "from %jd to %ju", intmax_t.min, uintmax_t.max)
Run Code Online (Sandbox Code Playgroud)


Top*_*ter 8

NSString可能支持以下所有内容,其中总结了\n( source )支持的格式说明符。

\n

\xc2\xa0 \xc2\xa0 格式化方法和 CFString 格式化函数支持的格式说明NSString符遵循 \xc2\xa0 IEEE printf 规范;说明符总结在下面的\xc2\xa0(表1)中。请注意,您还可以使用“ n$”位置说明符,例如\xc2\xa0 %1$@ %2$s。有关更多详细信息,请参阅\xc2\xa0 IEEE printf 规范。您还可以将这些格式说明符与 \xc2\xa0 NSLog\xc2\xa0 函数一起使用。

\n

格式说明符(表 1)

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
说明符描述
%@Objective-C 对象,如果可用,则打印为 \xc2\xa0 \xc2\xa0 返回的字符串descriptionWithLocale:,否则打印为 \xc2\xa0 description\xc2\xa0 返回的字符串。也适用于\xc2\xa0 CFTypeRef\xc2\xa0对象,返回\xc2\xa0 \xc2\xa0函数的结果CFCopyDescription
%%\'%\'\xc2\xa0 字符。
%d,\xc2\xa0%D有符号 32 位整数 ( int)。
%u,\xc2\xa0%U无符号 32 位整数 ( unsigned int)。
%x无符号 32 位整数 ( unsigned int),使用数字 0--9 和小写 a--f 以十六进制打印。
%X无符号 32 位整数 ( unsigned int),使用数字 0--9 和大写 A--F 以十六进制打印。
%o,\xc2\xa0%O无符号 32 位整数 ( unsigned int),以八进制打印。
%f64 位浮点数 ( double)。
%e64 位浮点数 ( double),以科学计数法打印,使用小写 e 引入指数。
%E64 位浮点数 ( double),以科学记数法打印,使用大写 E 来引入指数。
%g64位浮点数(double),以\xc2\xa0 \xc2\xa0的样式打印,如果%e指数小于--4或大于或等于精度,则以\xc2\xa0 %f\xc2的样式打印\xa0否则。
%G64位浮点数(double),以\xc2\xa0 \xc2\xa0的样式打印,如果%E指数小于--4或大于或等于精度,则以\xc2\xa0 %f\xc2的样式打印\xa0否则。
%c8 位无符号字符 ( unsigned char)。
%C16 位 UTF-16 代码单元 ( unichar)。
%s以 Null 结尾的 8 位无符号字符数组。由于 \xc2\xa0 %s\xc2\xa0 说明符会导致以系统默认编码解释字符,因此结果可能会发生变化,尤其是对于从右到左的语言。例如,对于 RTL,\xc2\xa0 %s\xc2\xa0 在字符方向性不强时插入方向标记。因此,最好避免使用 \xc2\xa0 %s\xc2\xa0 并显式指定编码。
%S16 位 UTF-16 代码单元的以 Null 终止的数组。
%p空指针 ( void *),以十六进制打印,包含数字 0--9 和小写 a--f,前导\xc2\xa0 0x
%a64 位浮点数 ( double),以科学记数法打印,以前导 \xc2\xa0 0x\xc2\xa0 和小数点前的一位十六进制数字使用小写 \xc2\xa0 p\xc2\xa0 来引入指数。
%A64 位浮点数 ( double),以科学记数法打印,前导\xc2\xa0 0X\xc2\xa0 和小数点前一位十六进制数字,使用大写\xc2\xa0 P\xc2\xa0 来引入指数。
%F64 位浮点数 ( double),以十进制表示法打印。
\n

长度修饰符(表 2)

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
长度修饰符描述
h长度修饰符,指定以下 \xc2\xa0 d、\xc2 o\xa0 、u\xc2\xa0 、\xc2\xa0x或 \xc2\xa0 X\xc2\xa0 转换说明符适用于 a\xc2\xa0 short\xc2\xa0or\xc2\ xa0 unsigned short\xc2\xa0 参数。
hh长度修饰符,指定以下 \xc2\xa0 d、\xc2 o\xa0 、u\xc2\xa0 、\xc2\xa0x或 \xc2\xa0 X\xc2\xa0 转换说明符适用于 a\xc2\xa0 signed char\xc2\xa0or\xc2\ xa0 unsigned char\xc2\xa0 参数。
l长度修饰符,指定以下 \xc2\xa0 d、\xc2 o\xa0 、u\xc2\xa0 、\xc2\xa0x或 \xc2\xa0 X\xc2\xa0 转换说明符适用于 a\xc2\xa0 long\xc2\xa0or\xc2\ xa0 unsigned long\xc2\xa0 参数。
ll,\xc2\xa0q长度修饰符指定以下\xc2\xa0 d、\xc2\xa0 ou\xc2\xa0 、\xc2\xa0x或\xc2\xa0 X\xc2\xa0 转换说明符适用于 a\xc2\xa0 long long\xc2\xa0or\xc2\ xa0unsigned long long参数。
L长度修饰符指定以下\xc2\xa0 a、\xc2\xa0 Ae\xc2\xa0 E、\xc2\xa0 f、\xc2\xa0 、\xc2\xa0 F、\xc2\xa0g或\xc2\xa0 G\xc2\xa0conversion说明符适用于 a\xc2\xa0 long double\xc2\xa0 参数。
z长度修饰符指定以下 \xc2\xa0 d、\xc2\xa0 o、\xc2\xa0 、 u\xc2\xa0x或 \xc2\xa0 X\xc2\xa0 转换说明符适用于 a\xc2\xa0 size_t
t长度修饰符指定以下 \xc2\xa0 d、\xc2\xa0 o、\xc2\xa0 、 u\xc2\xa0x或 \xc2\xa0 X\xc2\xa0 转换说明符适用于 a\xc2\xa0 ptrdiff_t
j长度修饰符,指定以下 \xc2\xa0 d、\xc2 o\xa0 、u\xc2\xa0 、\xc2\xa0x或 \xc2\xa0 X\xc2\xa0 转换说明符适用于 a\xc2\xa0 intmax_t\xc2\xa0or\xc2\ xa0 uintmax_t\xc2\xa0 参数。
\n
\n
\n

长度修饰符示例:

\n
#include <limits.h>\n\n// ...\n\nNSString *text = [NSString stringWithFormat:@"Signed %hhd, Unsigned %hhu", CHAR_MIN, UCHAR_MAX];\n
Run Code Online (Sandbox Code Playgroud)\n

或者用斯威夫特:

\n
let text = String(format: "Signed %hhd, Unsigned %hhu", CChar.min, CUnsignedChar.max)\n
Run Code Online (Sandbox Code Playgroud)\n
\n

平台依赖性

\n

OS X\xc2\xa0 使用多种数据类型 — NSInteger、\xc2\xa0 NSUIntegerCGFloat和 \xc2\xa0 CFIndex— 来提供在 32 位和 64 位环境中表示值的一致方法。在 32 位环境中,\xc2\xa0 NSInteger\xc2\xa0 和NSUInteger\xc2\xa0 \xc2\xa0 分别定义为 \xc2\xa0 int\xc2\xa0 和 \xc2\xa0 unsigned int。在 64 位环境中,\xc2\xa0NSInteger和 \xc2\xa0 NSUInteger\xc2\xa0 分别定义为 \xc2\xa0 long\xc2\xa0 和 \xc2\xa0 unsigned long。为了避免需要根据平台使用不同的 printf 样式类型说明符,您可以使用\xc2\xa0表 3 中所示的说明符。请注意,在某些情况下,您可能必须转换该值。

\n

表 3 \xc2\xa0\xc2\xa0 数据类型的格式说明符

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n
类型格式说明符注意事项
NSInteger%ld\xc2\xa0 或 \xc2\xa0%lx将值转换为\xc2\xa0 long
NSUInteger%lu\xc2\xa0 或 \xc2\xa0%lx将值转换为\xc2\xa0 unsigned long
CGFloat%f\xc2\xa0 或 \xc2\xa0%g%f\xc2\xa0 适用于格式化时的浮点数和双精度数;但请注意下面描述的扫描技术。
CFIndex%ld\xc2\xa0 或 \xc2\xa0%lx与\xc2\xa0 相同NSInteger
指针%p\xc2\xa0 或 \xc2\xa0%zx%p\xc2\xa0 将 \xc2\xa0 0x\xc2\xa0 添加到输出的开头。如果您不想这样做,请使用 \xc2\xa0 %zx\xc2\xa0 并且不进行类型转换。
\n
\n

以下示例说明了如何使用\xc2\xa0 %ld\xc2\xa0 来格式化\xc2\xa0 NSInteger\xc2\xa0 以及强制转换的使用。

\n
NSInteger i = 42;\nprintf("%ld\\n", (long)i);\n
Run Code Online (Sandbox Code Playgroud)\n

除了\xc2\xa0表3中提到的注意事项外,扫描时还有一种额外情况:\n您必须区分\xc2\xa0 float\xc2\xa0和\xc2\xa0的类型double。\n您应该使用\xc2\xa0 %f\ xc2\xa0 表示浮点数,\xc2\xa0 %lf\xc2\xa0 表示双精度。\n如果需要将\xc2\xa0 scanf\xc2\xa0(或其变体)与\xc2\xa0 一起使用CGFloat,请切换到\xc2\xa0 double\xc2\ xa0 相反,\n并将\xc2\xa0 double\xc2\xa0 复制到\xc2\xa0 CGFloat

\n
CGFloat imageWidth;\ndouble tmp;\nsscanf (str, "%lf", &tmp);\nimageWidth = tmp;\n
Run Code Online (Sandbox Code Playgroud)\n

请务必记住,\xc2\xa0 %lf\xc2\xa0CGFloat在 32 位或 64 位平台上都不能正确表示 \xc2\xa0 \xc2\xa0。\n这与 \xc2\xa0 不同%ld,后者适用于 \xc2\xa0long在所有情况下都是 \xc2\xa0。

\n