C语言printf函数是可以通过%s来指定输出格式的,在s前输出整数来约束输出的最小宽度,如果结果没达到最小宽度,则会填充空格。
最简单的输出:
#include <stdio.h>
int main() {
printf("%10s\n", "hello");
}
以上代码输出结果会在hello之前填充5个空格,从而使结果达到最小宽度。
发现问题
当我输出5个中文字符的时候,也想和上面的hello一样,让前面填充5个空格,但是输出的时候却不会填充。
#include <stdio.h>
int main() {
printf("%10s\n", "hello");
printf("%10s\n", "一二三四五");
}
问题原因
hello是属于单字节字符,而中文则是多字节字符;对于这两者的字符串,printf在计算长度时的处理方式是不同。具体来说:
单字节字符串
- 对于单字节字符串(如英文字符串),printf会计算每个字符的数量。
- 格式化符"%10s"中的数字会与字符串中的字符数量进行比较。
- 如果字符数量小于指定的最小宽度,则会填充空格。
- 例如"%10s" 和字符串"hello",由于"h"只有5个字符,小于10,所以会填充空格。
- 所以对单字节字符串,printf是根据字符数量来计算的。
多字节字符串
- printf不会计算多字节字符串的实际字符数量。
- 而是直接采用整个字符串的字节数长度来比较。
- 例如"%10s" 和字符串"一二三四五",由于在UTF-8编码中,每个中文字符通常由3个字节来表示。所以,对于字符串"一二三四五",它实际上由9个字节组成。每个中文字符占用3个字节,总共有5个中文字符,因此该字符串的字节数长度为15。大于10,所以不会填充空格。
- 可以使用strlen()函数,计算字节数
总结
- 单字节字符串:计算字符数量
- 多字节字符串:计算字节数量
#include <stdio.h>
#include <string.h>
int main()
{
// 填充空格
printf("%10s\n", "hello");
printf("%10s\n", "一二三");
printf("字符串的字节数长度为:%zu\n", strlen("一二三"));
// 不填充空格
printf("%10s\n", "一二三h");
printf("字符串的字节数长度为:%zu\n", strlen("一二三h"));
printf("%10s\n", "一二三四五");
printf("字符串的字节数长度为:%zu\n", strlen("一二三四五"));
return 0;
}