本文最后更新于 2025年8月14日 星期四 10:51
sprintf
是个变参函数,作用是打印到字符串。其定义如下:
1
| int sprintf (char *__stream, const char *__format, ...);
|
一、格式化数字字符串
sprintf
最常见的应用为把整型打印到字符串中,所以,sprintf
在大多数场合可以替代 itoa。
1 2 3 4 5 6 7 8 9 10 11 12 13
| char s[64];
sprintf(s, "%d", 123);
sprintf(s, "%4d%4d", 123, 456); sprintf(s, "%-4d%4d", 123, 456);
sprintf(s, "%4x", 123); sprintf(s, "%-4X", 123); sprintf(s, "%04X", 123);
|
注意一个符号扩展的问题:假如我们想用 16 进制表示短整型
-1,因为一个短整型占 2 个字节,所以我们希望用 4 位 16
进制数来打印它:
1 2 3
| short s1 = -1; sprintf(s, "%04X", s1); sprintf(s, "%04X", (unsigned short)s1);
|
产生 "FFFFFFFF",是因为 sprintf
是个变参函数,除前两个参数外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个
“%X” 就能得知当初函数调用前参数压栈时被压进来的到底是个 4
字节的整型还是个 2 字节的短整型,所以采取了统一 4
字节的处理方式,导致参数压栈时做了符号扩展,扩展成了 32 位的整型
-1,打印时 4 个位置不够了,就把 32 位整型 -1 的 8 位 16
进制都打印出来了。
注意 8 进制和 16
进制都不会打印出负数,都是无符号的,实际上也就是变量的内部编码的直接的
16 进制或 8 进制表示。
二、打印浮点数
浮点数使用格式符 "%f" 控制,默认保留小数点后 6
位数字:
1 2 3 4 5 6
| sprintf(s, "%f", 3.1415926);
sprintf(s, "%8.3f", 3.1415626); sprintf(s, "%-8.3f", 3.1415626); sprintf(s, "%.3f", 3.1415626);
|
1 2
| sprintf(s, "%.2f", 1); sprintf(s, "%.2f", (double)1);
|
三、连接字符串
sprintf 能够连接字符串,在许多场合可以替代
strcat,并且它可以同时在字符串中间插入别的内容,非常灵活。如:
1 2 3
| char* s1 = "Hello"; char* s2 = "world"; sprintf(s, "%s, %s!", s1, s2);
|
打印字符串也可以指定宽度:
1 2 3 4 5 6 7 8 9 10 11 12 13
| char a1[] = {'A', 'B', 'C'}; char a2[] = {'D', 'E', 'F'}; sprintf(s, "%s%s", a1, a2); sprintf(s, "%3s%3s", a1, a2); sprintf(s, "%.3s%.3s", a1, a2);
sprintf(s, "%.1s%.2s", a1, a2); sprintf(s, "%.*s%.*s", 1, a1, 2, a2); sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
sprintf(s, "%#0*X", 8, 128); sprintf(s, "%*.*f", 10, 2, 3.1415926);
|
四、打印地址信息
有时调试程序时,我们可能想查看某些变量或者成员的地址,由于地址或者指针也不过是个
32 位的数,你可以打印地址信息:
1 2 3 4 5
| int i; sprintf(s, "%u", &i); sprintf(s, "%08X", &i); sprintf(s, "%p", &i); sprintf(s, "%0*x", 2 * sizeof(void *), &i);
|
五、利用 sprintf
的返回值
sprintf
返回了本次函数调用最终打印到字符缓冲区中的字符数目。也就是说每当一次
sprintf 调用结束以后,无须再调用一次
strlen 就能知道结果字符串的长度。如:
1
| int len = sprintf(s, "%d", i);
|
对于正整数来说,len 便等于整数 i 的 10 进制位数。
下面的是个完整的例子,产生 10 个 [0, 100)
之间的随机数,并将他们打印到一个字符数组 s 中,以逗号分隔开。
1 2 3 4 5 6 7 8 9 10 11 12
| #include <bits\stdc++.h> int main() { srand(time(0)); char s[64]; int offset = 0; for (int i = 1; i <= 10; i++) { offset += sprintf(s + offset, "%d,", rand() % 100); } s[offset - 1] = '/n'; printf(s); return 0; }
|
六、strftime
strftime 专门用于格式化时间字符串,用法跟
sprintf 很像,但要调用者指定缓冲区的最大长度。如:
1 2 3
| time_t t = time(0); char s[64]; strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));
|
sprintf 在 MFC 中对应
CString::Format,strftime 在 MFC 中对应
CTime::Format。
本文部分内容整理自互联网。