朝花夕拾 - C#格式化字符串
格式字符串
在使用write
或writeline
时可以有一个或以上的参数
- 如果不止一个参数,参数间使用逗号分隔
- 第一个参数必须是字符串,称为
格式字符串
,输出串中可以包含替代标记
- 替代标记在格式字符串中标出位置,输出中将用一个值进行替代
- 替代标记由
花括号{}
和一个整数
组成,其中整数是替换值的数字位置
,替换值的位置从0
开始编号
例子
string name = "hahaha";
int simple = 10;
Console.WriteLine("Hello, World! {0} | {1}", name, simple);
输出
Hello, World! hahaha | 10
索引越界
string name = "hahaha";
int simple = 10;
Console.WriteLine("Hello, World! {0} | {2}", name, simple);
异常提示
Unhandled exception. System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
字符串插值
C#6.0 引入了字符串插值
它是通过直接替代字符串中的替代标记
进行的,这种方式更加方便并且符合阅读习惯
- 使用字符串差值时 字符串前必须添加
$
标记
例子
string name = "hahaha";
int simple = 10;
Console.WriteLine($"Hello, World! {name} | {simple}");
输出
Hello, World! hahaha | 10
格式化字符串
标准数字格式说明符
C#提供了很多方便的说明符对字符进行格式化
string name = "hahaha";
int positiveInt= 110;
long bigInt = 123456789;
int decimalInt = -10;
double price = 12.5;
float pricef = -12.543553f;
double general = 4.123456789123456789;
double percentage = 0.123456789;
名称 | 字符 | 意义 | 示例 |
---|---|---|---|
货币 | C,c | 使用货币符号把值格式化为货币,符号取决于程序所在的PC所在区域 格式 {C/c{精度说明符}( 小数位数 ) |
Console.WriteLine("{0:c4}", price); Console.WriteLine($"{price:C5}"); 输出 ¥12.5000 ¥12.50000 |
十进制数 | D,d | 十进制字符串,负数时有负号 格式 {D/d{精度说明符}( 补零位数 ) |
Console.WriteLine("十进制数: {0:d8}", decimalInt); Console.WriteLine($"十进制数: {decimalInt:D5}"); 输出 -00000010 -00010 |
浮点数 | F,f | 浮点数,负数时有负号 格式 {F/f{精度说明符}( 小数位数 ) |
Console.WriteLine("浮点数 float: {0:f4}", pricef); Console.WriteLine($"浮点数 double: {price:f5}"); 输出 -12.5433 12.50000 |
常规(未指定) | G,g | 未指定或指定为G/g时,会根据值类型转换,浮点数时依然会四舍五入 格式 {G/g{精度说明符( 小数位数 )} |
Console.WriteLine("常规: {0:g5}", general); Console.WriteLine($"常规: {general:g}", general); 输出 4.1235 4.123456789123456 |
十六进制 | G,g | 转换为十六进制,字符大小写会改变十六进制字符串的大小写 精度如果大于长度会在前面补零,精度不够会超过精度限制 格式 {X/x{精度说明符( 补零位数 )} |
Console.WriteLine("十六进制: {0:X4}", decimalInt); Console.WriteLine($"十六进制 {positiveInt:x6}"); 输出 FFFFFFF6 00006e |
数字 | N,n | 转换浮点数输出,并且会在位数之间加入, 具体是, 还是空格 根据设置的区域而定格式 {X/x{精度说明符( 小数位数 )} |
Console.WriteLine("数字: {0:N}", general); Console.WriteLine($"数字: {bigInt:N5}"); 输出 4.12 123,456,789.00000 |
百分比 | P,p | 转换为百分比输出,默认保留两位 不足的地方会四舍五入 格式 {P/p{精度说明符( 小数位数 )} |
Console.WriteLine("百分比: {0:P}", percentage); Console.WriteLine($"百分比: {percentage:p4}"); 输出 12.35% 12.3457% |
原始值 | R,r | 如果之后用Parse 转换为数字,保证其和原始值相同格式 {R/r{精度说明符( 忽略,不起作用 )} |
Console.WriteLine("原始值: {0:R}", general); Console.WriteLine($"原始值: {general:r9}"); 输出 4.123456789123456 4.123456789123456 |
科学计数法 | E,e | 转换为科学计数法,大小写和字符保持一致 精度不够时四舍五入 格式 {R/r{精度说明符( 小数位数 )} |
Console.WriteLine("科学计数法: {0:E4}", general); Console.WriteLine($"科学计数法: {general:E6}"); 输出 4.1235E+000 4.123457E+000 |
对齐说明符
对齐说明符表示字段中字符的最小宽度
如果不进行对齐我们的代码会输出这样的结果
货币符号: ¥12.5000
货币符号: ¥12.50000
十进制数: -00000010
十进制数: -00010
浮点数 float: -12.5436
浮点数 double: 12.50000
常规: 4.1235
常规: 4.123456789123456
十六进制: FFFFFFF6
十六进制 00006e
十六进制 6e
数字: 4.12
数字: 123,456,789.00000
百分比: 12.35%
百分比: 12.3457%
原始值: 4.123456789123456
原始值: 4.123456789123456
科学计数法: 4.1235E+000
科学计数法: 4.123457E+000
对于强迫症来说这肯定不能接受啊
来一段代码说明对齐说明符
Console.WriteLine("对齐说明符: |{0, 10}|", positiveInt);
Console.WriteLine("对齐说明符: |{0, -10}|", positiveInt);
Console.WriteLine($"对齐说明符: |{positiveInt, 10}|");
Console.WriteLine($"对齐说明符: |{positiveInt, -10}|");
Console.WriteLine("对齐说明符: |{0, 10:f11}|", percentage);
Console.WriteLine("对齐说明符: |{0, -10:f4}|", percentage);
输出
对齐说明符: | 110|
对齐说明符: |110 |
对齐说明符: | 110|
对齐说明符: |110 |
对齐说明符: |0.12345678900|
对齐说明符: |0.1235 |
- 正数表示右对齐,负数表示左对齐
- 如果字符超出了限制的字符,则原限制失效
- 在对齐基础上可以增加格式说明符 格式
{{变量}, {字符长度}:{格式说明符}}
内插字符串转义序列
C#8.0
以后可以使用逐字转义序列,进行转义
格式: 在字符串前加 @$
或者 $@
都可以
- 以
@
加在字符串开头时,字符换内的字符不会进行转义 - 如果使用
@$
要在字符串中包含{
或}
,需要使用{{
或}}
代码示例
var xs = new int[] { 1, 2, 7, 9 };
var ys = new int[] { 7, 9, 12 };
Console.WriteLine($"Find the intersection of the {{{xs}}} and {{{string.Join(", ",ys)}}} sets.");
var userName = "Jane";
var stringWithEscapes = $"C:\\Users\\{userName}\\Documents";
var verbatimInterpolated = $@"C:\Users\{userName}\Documents";
Console.WriteLine(stringWithEscapes);
Console.WriteLine(verbatimInterpolated);
在内插字符串中使用三元运算符
由于:
在内插表达式选项中有特殊含义(比如: 字符格式说明符前要使用),所以条件运算符需要放在括号内
var rand = new Random();
for (int i = 0; i < 7; i++)
{
Console.WriteLine($"Coin flip: {(rand.NextDouble() < 0.5? "heads" : "tails")}");
}
Coin flip: heads
Coin flip: tails
Coin flip: heads
Coin flip: heads
Coin flip: tails
Coin flip: heads
Coin flip: tails