# 格式化字符串

请参考：[数据类型 - 字符串](../../../language-reference/datatype/datatype.md#varstring)

## 一. 格式化函数

string.format 用来格式化字符串(按指定的规则连接字符串或其他变量并返回新的字符串) 。使用方法与 C 语言的 printf 函数类似( 实际上很多编程语言中都有类似的格式化函数 ) 。
  
`result = string.format(fm,...);`

第一个字符串参数 @fm 指定输出的格式，每个 `%` 符号后面是一个格式化表达式，每个格式化表达式按顺序对应后面的参数。

所以用了 n 个格式化表达式，就必须在后面添加 n 个参数。  
  
下面是一个简单的例子：

```aardio
var int = 123;
var str = "字符串"

//下面的 %s 对应参数 str, %i 对应参数 int
var result = string.format("这是字符串:'%s' 这是数字值 %i",str,int);
 
//%05i表示格式化为至少五位的数字,不足在前面补 0
var str = string.format("%05i",int); 
```  

## 二. 格式化语法 

格式化表达式：

`%[零个或多个标志][最小字段宽度][.精度]格式化代码`

> 注意: 上面的方括号 `[]` 表示可选部分。 
  
### 格式化代码 <a id="type" href="#type">&#x23;</a>

代码 c  
参数：数字值(number)  
含义：参数被裁剪为8位字节码并作为字符进行打印。

代码 i,d  
参数：数字值(number)  
含义：参数作为一个十进制整数打印。如果给出了精度而且值的位数小于精度位数，前面就用0填充。

代码 u,o,b,x,X  
参数：数字值(number)  
含义：参数作为一个无符号数字值打印，u使用十进制，o使用八进制，b使用二进制，x或X使用十六进制，两者的区别是x约定使用abcdef，而X约定使用ABCDEF。 %u,%o,%x,%X 等格式代码也可用于格式化 math.size64 对象（按64位无符号数值格式化 ）。

代码 e,E  
参数：数字值(number)  
含义：参数根据指数形式打印。例如，6.023000e23是使用代码e，6.023000E23是使用代码E。小数点后面的位数由精度字段决定，缺省值是6。

代码 f  
参数：数字值(number)  
含义：参数按照的常规浮点格式打印。精度字段决定小数点后面的位数，缺省值是6。

代码 g,G  
参数：数字值(number)  
含义：参数以%f或%e（如G则%E）的格式打印，取决于它的值。如果指数大于等于-4但小于精度字段就使用%f格式，否则使用指数格式。

代码 s  
参数：字符串值(string)  
含义：打印一个字符串。

代码 q  
参数：(无)  
含义：打印一个字符串，并将字符串置于一对引号中，如果字符串中包含引号换行等自动添加转义符。如果要读取一个字符串传为代码。为避免用户恶意注入引号等特殊字符，可以使用%q进行格式化。

代码 %  
参数：(无)  
含义：取消%转义打印一个%字符,即用%%表示本来的%。

### 格式化标志 <a id="flags" href="#flags">&#x23;</a>


标志 `-`  
含义：如果在填充宽度前加上 `-` 号，则值在填充结果中左对齐（缺省情况下是右对齐）。

标志 `0` 
含义：当数值为右对齐时，缺省情况下是使用空格填充值左边未使用的列。这个标志表示用零填充，它可用于格式化代码 d,i,u,o,x,X,e,E,f,g 和 G 。  
使用格式化代码 d,i,u,o,x 和 X 时，如果给出了精度字段，标志`0` 就被忽略。如果格式代码中出现了负号，标志`0` 也没有效果。

标志 `+`  
含义：当用于一个格式化某个有符号值代码时，如果值非负，正号标志就会给它加上一个正号。如果该值为负，就像往常一样显示一个负号。在  
缺省情况下，正号并不会显示。

标志 空格  
含义：只用于转换有符号值的代码。当值非负时，这个标志把一个空格添加到它开始的位置。注意这个标志和正号标志是相互排斥的，如果两个  
同时给出，空格标志便被忽略。

扩展标志 `#`  
含义：用于选择某些代码的另一种转换形式。  

示例：   
  - `#o` 保证产生的值以一个零开头  
  - `#x`,`#X` 在非零值前面加 `0x` 前缀（ `%#X` 则为 `0X`）  
  - `#e`,`#E`,`#f` 确保结果始终包含一个小数点，即使它后面没有数字  
  - `#g`,`#G` 和上面的 `#e`, `#E` 和 `#f` 代码相同。另外，缀尾的 0 并不从小数中去除。

### 字段宽度 <a id="width" href="#width">&#x23;</a>


字段宽度是一个十进制整数，用于指定将出现在结果中的最小字符数。如果值的字符数少于字段宽度，就对它进行填充以增加长度。  
  
### 精度 <a id="precision" href="#precision">&#x23;</a>


精度以一个句点开头，后面跟一个可选的十进制数。如果未给出整数，精度的缺省值为零。

对于格式化代码为 d,i,u,o,x 或 X 的转换，精度字段指定将出现在结果中的最小的数字个数并覆盖零标志。如果转换后的值的位数小于宽度，就在它的前面插入零。如果值为零且精度也为零，则转换结果就不会产生数字。

对于格式化代码 e,E 或 f 类型的转换，精度决定将出现在小数点之后的数字位数。

对于格式化代码 g 和 G 的转换，它指定将出现在结果中的最大有效位数。

格式化代码为 s 的转换，精度指定将被转换的最多的字符数。

5. 格式语法示例   

| 格式代码 | A | ABC | ABCDEFGH |
| --- | --- | --- | --- |
| `%s` | A | ABC | ABCDEFGH |
| `%5s` | ####A | ##ABC | ABCDEFGH |
| `%.5s` | A | ABC | ABCDE |
| `%5.5s` | ####A | ##ABC | ABCDE |
| `%-5s` | A#### | ABC## | ABCDEFGH |


| `格式代码` | 1 | \-12 | 12345 | 123456789 |
| --- | --- | --- | --- | --- |
| `%d` | 1 | \-12 | 12345 | 123456789 |
| `%6d` | #####1 | ###-12 | #12345 | 123456789 |
| `%.4d` | 0001 | \-0012 | 12345 | 123456789 |
| `%6.4d` | ##0001 | #-0012 | #12345 | 123456789 |
| `%-4d` | 1#### | \-12# | 12345 | 123456789 |
| `%04d` | 0001 | \-012 | 12345 | 123456789 |
| `%+d` | +1 | \-12 | +12345 | +123456789 |

  

| `格式代码` | 1 | .01 | .00012345 | 12345.6789 |
| --- | --- | --- | --- | --- |
| `%f` | 1.000000 | 0.010000 | 0.000123 | 12345.678900 |
| `%10.2f` | ######1.00 | #####0.01 | ######0.00 | ##12345.67 |
| `%e` | 1.000000e+00 | 1.000000e-02 | 1.234500e-04 | 1.234568e+04 |
| `%.4e` | 1.0000e+00 | 1.0000e-02 | 1.2345e-04 | 1.2346e+04 |
| `%g` | 1 | 0.01 | 0.00012345 | 12345.7 |

  

| `格式代码` | 6.023e23 |
| --- | --- |
| `%f` | 60229999999999975882752.000000 |
| `%10.2f` | 60229999999999975882752.00 |
| `%e` | 6.023000e+23 |
| `%.4e` | 6.0230e+23 |
| `%g` | 6.023e+23 |

用上面的格式化函数可以轻松实现数字的进制转换( 请参考：[数值与进制](../../../language-reference/datatype/number.md) )
  
```aardio
import console; 

//数字转换为二进制字符串
str = string.format("2#%b",23 );
console.log(str)

//二进制字符串转换为数字
n = tonumber(str,2)

//数字转换为八进制字符串
str = string.format("8#%o",23 );
console.log(str)

//八进制字符串转换为数字
n = tonumber(str,8)

//数字转换为十六进制字符串
str = string.format("%#x",23 );
console.log(str)

//十六进制字符串转换为数字
n = tonumber(str,16)

console.pause();
```