wsprintf()函数与输出格式化
2010-08-08
在C语言中格式化字符串可以使用printf,但是在WINDOWS编程设计中却行不通了,但是却有变通的方法,那就是用 wsprintf这个函数。它的格式如下:
1 | int wsprintf ( LPTSTR lpOut, // 指向需要输出的字符串的指针 |
2 | LPCTSTR lpFmt, //指向格式控制字符串的指针 |
3 | …… // 其他可选参数 |
4 | ); |
wsprintf(缓冲区, 格式, 要格式化的值);
第一个参数是字符缓冲区,后面是格式字符串,wsprintf不是将格式化结果写到标准输出,而是将其写入缓冲区中,该函数返回该字符串的长度。
比如我们想通过MessageBox来输出一个整形变量的值,可以用以下代码实现:
1 | char szBuffer[100]; |
2 | ing number=100; |
3 | wsprintf(szBuffer, "%d" ,number); |
4 | MessgaeBox(NULL,szBrffer,TEXT( "格式化字符串" ),0); |
这个函数除了将内容格式化输出到第一个参数所提供的字符串缓冲区以外,其它功能与printf函数相同。
wsprintf对应的字符串是宽字符型wchar_t,即一个字符占用2个字节的内存空间。
sprintf对应的字符串是字符类型为char,即一个字符占用1个字节的内存空间。
sprintf是用于对ASCII码的127个字符进行操作,wsprintf是对UNICODE的多语言字符进行操作。如:
1 | sprintf (buffer, "ascii" ); |
2 | wsprintf(buffer, L "unicode" ); |
3 | wsprintf(filepath, L "%s\\%s" , folder_name, find_data.cFileName); |
wsprintf函数能够将一组字符序列按lpFmt参数指定的格式转换,然后保存在lpOut参数指定的字符缓冲区中等待输出。其中,字符序列由可选参数决定,而可选参数的数目和具体内容应该与lpFmt所指定的格式一致。
如果wsprintf函数操作成功,则返回输出字符的数目,但这个字符数目不包括表示结束的NULL标志。如果操作失败,返回的整数值将与输出的字符数目不相符。
1 | BOOL TextOut( HDC hdc, // 设备描述表句柄 |
2 | int nXStart, // 文本输出起始点 X坐标 |
3 | int nYStart, // 文本输出起始点 Y坐标 |
4 | LPCTSTR lpString, // 指向输出字符串的指针 |
5 | int cbString // 字符串中字符的数目 |
6 | ); |
TextOut函数能够用当前设定的字体在窗口的指定部位输出一段文本信息。如果操作成功则返回一非零值,否则返回零值。捕获键盘消息的信息主要根据表中的描述,通过使用按位操作确定某些特定位的值,然后再判断具体的状态。
wsprintf的用法的一个程序片断:
1 | int x=6 |
2 | LPTSTR szBuffer= new TCHAR [1024]; |
3 | wsprintf(szBuffer, "%d" ,x); //将变量x的值格式化为数字(%d)输出到缓冲区szBuffer指向的内存单元。 |
4 | MessageBox(NULL,szBuffer, " " ,MB_OK); |
格式化规定符:
- %d 格式化为十进制有符号整数输出到缓冲区
- %u 格式化为十进制无符号整数输出到缓冲区
- %f 格式化为浮点数输出到缓冲区
- %s 格式化为字符串输出到缓冲区
- %c 格式化为单个字符输出到缓冲区
- %e 格式化为指数形式的浮点数输出到缓冲区
- %x 格式化为无符号以十六进制表示的整数(a-f小写输出)输出到缓冲区
- %X 格式化为无符号以十六进制表示的整数(a-f大写输出)输出到缓冲区
- %0 格式化为无符号以八进制表示的整数输出到缓冲区
- %g 格式化为自动选择合适的表示法输出到缓冲区
说明:
- 可以在"%"和字母之间插进数字表示最大场宽。例如: %3d 表示输出3位整型数,不够3位右对齐。%9.2f 表示输出场宽为9的浮点数,其中小数位为2,整数位为6,小数点占一位,不够9位右对齐。%8s 表示输出8个字符的字符串,不够8个字符右对齐。如果字符串的长度、或整型数位数超过说明的场宽,将按其实际长度输出。但对浮点数,若整数部分位数超过了说明的整数位宽度,将按实际整数位输出;若小数部分位数超过了说明的小数位宽度,则按说明的宽度以四舍五入输出。另外,若想在输出值前加一些0,就应在场宽项前加个0。例如: %04d 表示在输出一个小于4位的数值时,将在前面补0使其总宽度为4位。如果用浮点数表示字符或整型量的输出格式,小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9,则第9个字符以后的内容将被删除。
- 可以在"%"和字母之间加小写字母l,表示输出的是长型数。例如: %ld 表示输出long整数,%lf 表示输出double浮点数。
- 可以控制输出左对齐或右对齐,即在"%"和字母之间加入一个"-" 号可说明输出为左对齐,否则为右对齐。例如: %-7d 表示输出7位整数左对齐。%-10s 表示输出10个字符左对齐。
转换说明及作为结果的打印输出
%A 浮点数、十六进制数字和p-记法(C99)
%c 一个字符
%d 有符号十进制整数
%e 浮点数、e-记数法
%E 浮点数、E-记数法
%f 浮点数、十进制记数法
%g 根据数值不同自动选择%f或%e.
%G 根据数值不同自动选择%f或%e.
%i 有符号十进制数(与%d相同)
%o 无符号八进制整数
%p 指针
%s 字符串
%u 无符号十进制整数
%x 使用十六进制数字0f的无符号十六进制整数
%X 使用十六进制数字0f的无符号十六进制整数
%% 打印一个百分号
{
//for int
int i=30122121;
long i2=309095024l;
short i3=30;
unsigned i4=2123453;
printf("%d,%ld ",i,i2);// 试验不出%ld和%d之间的差别,因为long是4bytes
printf("%hd,%hd ",i,i3);//试验了%hd和%d之间的差别,因为short是2bytes
//for string and char
char ch1="d";
unsigned char ch2=160;
char *str="Hello everyone!";
printf("%c,%u,%s ",ch1,ch2,str );//unsigned char超过128的没有字符对应
float fl=2.566545445F;//or 2.566545445f
double dl=265.5651445;
long double dl2=2.5654441454;
//%f没有e格式,默认6位仅只小数点后面包含6位
//%e采用e格式,默认6位为转化后的小数点后面的6位
printf("%f,%e,%g,%.7f ",fl,dl,dl,dl);
printf("%f,%E,%G,%f ",fl,dl,dl,dl);//%F is wrong
printf("%.8f,%.10e ",fl,dl);
printf("%.8e,%.10f ",fl,dl);
int *iP=&i;
char *iP1=new char;
void *iP2;//dangerous!
printf("%p,%p,%p ",iP,iP1,iP2);
//其他知识:负号,表示左对齐(默认是右对齐);%6.3,6表示宽度,3表示精度
char *s="Hello world!";
printf(":%s: :%10s: :%.10s: :%-10s: :%.15s: :%-15s: :%15.10s: :%-15.10s: ",
s,s,s,s,s,s,s,s);
printf(":%g: :%10g: :%.10g: :%-10g: :%.15g: :%-15g: :%15.10g: :%-15.10g: ",
ddd,ddd,ddd,ddd,ddd,ddd,ddd,ddd);
//还有一个特殊的格式%*.* ,这两个星号的值分别由第二个和第三个参数的值指定
printf("%*.*f ", 3,3, 1.25456f);
}
Character | Type | Output format |
返回值 |
| sprintf(myString, "address [%0*d]\n",8, myFunc)返回值是 strlen(myString)或者说缓冲区实际长度. |
* (.*) | all | 这个字符用法为不定长的长度,例如%2d,%3d, %*n , %.*f , etc; printf( "address [%0*d]\n",8, myFunc) == printf( "address [%08d]\n", myFunc); |
% | None | %%打印一个% |
0, #, -, +,(space) |
| 0,+, -,为右对齐或者左对齐。例如 printf(“%-8d%8d”,1234,5677),默认为右对齐(“+”), 0做补位填充使用 Space为空位,如果是space和”+”,没有其他,这些space将被忽略, # |
c | int or int_t | 单个字符,如果使用wprintf将是宽字符 |
C | int or int_t | 宽字符如果使用wprintf将是单字符 |
s | String | 单字节字符串使用printf如果使用wprintf就是宽字符串,如果空串,结果是"(null)" |
S | String | 宽字符串使用printf如果使用wprintf就是单字节字符串,如果空串,结果是"(null)" |
w | String,char | 打印 char or string,宽字符打印,不喜欢用 W2A的用这个 sprintf(str,"%ws",L"abcde"); |
d,i,I64I32,I | Int | 十进制整形 I64d, i64d 打印64位整形 ui64d无符号64位整形,末尾d不是必须,I与平台相关。 |
l(小写L),ll | Int | 长整型 printf( "%ld", myFunc), ll为(long,long) |
h | Int | 短整形,四字节截取成双字节。 |
L | Double,float | 打印成Long double 类型.作用于 e,E,f,g,G |
o | int | 八进制无符号整形 |
u | int | 无符号整形 |
x | int | 无符号十六进制整形,小写 “abcdef” |
X | int | 无符号十六进制整形,大写 “ABCDEF” |
e | double | 3.9265e+2,幂形式的浮点数,小写e |
E | double | 3.9265E+2,幂形式的浮点数,大写E |
f | double | 打印单精度浮点数 |
g | double | 短的 %e或者%f |
G | double | 短的 %E或者%f |
a | double | 有符号,双精度浮点数指针地址 0Xh.hhhh p±dd |
A | double | 有符号,双精度浮点数指针地址 0Xh.hhhh P±dd |
n | Pointer to integer | 到目前为止缓冲区都有啥取之.printf( "12345%n6789\n", &i ); i就等于5啦 |
p | Pointer tovoid | 打印物理地址,相当于printf( "%0*x", 2 * sizeof(void *), &i); |