实验:把长整形转换成字符串
#include <stdio.h>
i nt main( int argc, char ** argv )
{
FILE* file = fopen( "output.txt" , "w" );
char num[5];
for ( int i = 1; i < 3600; i++ )
{
sprintf( num, "%06d" , i );
fprintf( file, "%s/n" , num );
}
fclose( file );
return 1;
}
【注】以上 code 在 VS08 下抛出一个异常:“ Stack around the variable 'num' was corrupted ”,原因还在调查中
【总结】强大的 sprintf 函数
部分内容载自 《 优快云 社区电子杂志 ——C/C++ 杂志》
Sprintf : 将字串格式化 ,功能细节如下:
在头文件 #include<stdio.h> 中
语法 : int sprintf(string format, mixed [args]...);
返回值:字符串长度( strlen )
1. 处理字符方向。 - 负号时表时从后向前处理。
2. 填空字元。 0 的话表示空格填 0 ;空格是内定值,表示空格就放着。
3. 字符总宽度。为最小宽度。
4. 精确度。指在小数点后的浮点数位数。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
转换字符
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
% 印出百分比符号,不转换。
b 整数转成二进位。
c 整数转成对应的 ASCII 字元。
d 整数转成十进位。
f 倍精确度数字转成浮点数。
o 整数转成八进位。
s 整数转成字串。
x 整数转成小写十六进位。
X 整数转成大写十六进位。
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
关于 sprintf 的讨论
在将各种类型的数据构造成字符串时, sprintf 的强大功能很少会让你失望。由于 sprintf 跟 printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致 sprintf 比 printf 有用得多。
sprintf 是个变参函数,定义如下:
int sprintf( char *buffer, const char *format [, argument] ... );
除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:
格式化字符串上。
printf 和 sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以 “%” 开头的格式说明符( format specifications )来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。
格式化数字字符串
sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以, spritnf 在大多数场合可以替代
itoa 。
如:
// 把整数 123 打印成一个字符串保存在 s 中。
sprintf(s, "%d", 123); // 产生 "123"
可以指定宽度,不足的左边补空格:
sprintf(s, "%8d%8d", 123, 4567); // 产生: " 123 4567"
当然也可以左对齐:
sprintf(s, "%-8d%8d", 123, 4567); // 产生: "123 4567"
也可以按照 16 进制打印:
sprintf(s, "%8x", 4567); // 小写 16 进制,宽度占 8 个位置,右对齐
sprintf(s, "%-8X", 4568); // 大写 16 进制,宽度占 8 个位置,左对齐
这样,一个整数的 16 进制字符串就很容易得到,但我们在打印 16 进制内容时,通常想要一种左边补 0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个 0 就可以了。
sprintf(s, "%08X", 4567); // 产生: "000011D7"
上面以 ”%d” 进行的 10 进制打印同样也可以使用这种左边补 0 的方式。
这里要注意一个符号扩展的问题:比如,假如我们想打印短整数( short ) -1 的内存 16 进制表示形式,在 Win32 平台上,一个 short 型占 2 个字节,所以我们自然希望用 4 个 16 进制数字来打印它:
short si = -1;
sprintf(s, "%04X", si);
产生 “FFFFFFFF” ,怎么回事?因为 spritnf 是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个 “%X” 就能得知当初函数调用前参数压栈时被压进来的到底是个 4 字节的整数还是个 2 字节的短整数,所以采取了统一 4 字节的处理方式,导致参数压栈时做了符号扩展,扩展成了 32 位的整数 -1 ,打印时 4 个位置不够了,就把 32 位整数 -1 的 8 位 16 进制都打印出来了。
如果你想看 si 的本来面目,那么就应该让编译器做 0 扩展而不是符号扩展(扩展时二进制左边补 0 而不是补符号位):
sprintf(s, "%04X", (unsigned short)si);
就可以了。或者:
unsigned short si = -1;
sprintf(s, "%04X", si);
sprintf 和 printf 还可以按 8 进制打印整数字符串,使用 ”%o” 。注意 8 进制和 16 进制都不会打
印出负数,都是无符号的,实际上也就是变量的内部编码的直接的 16 进制或 8 进制表示。