Printf的格式控制和使用技巧

来源:互联网 发布:4张青眼白龙淘宝 编辑:程序博客网 时间:2024/06/05 17:42

printf tricks

  前言:发现一个小小的printf既然有这么多的功能我不知道,强大的“二八法则”,再次证实了它的威力。

转自http://www.georgevreilly.com/blog/2005/06/02/PrintfTricks.aspx

Printf  tricks

It may be old-fashioned, but I still find printf (and sprintf and _vsnprintf) incredibly useful, both for printing debug output and for generating formatted strings.

Here are a few lesser-known formats that I use again and again. See MSDN for the full reference.

A quick review of some of the basics

%04x - 4-digit hex number with leading zeroes

%x prints an int in hexadecimal.

%4x prints a hex int, right-justified to 4 places. If it's less than 4 digits, it's preceded by spaces. If it's more than 4 digits, you get the full number.

%04x prints a hex int, right-justified to 4 places. If it's less than 4 digits, it's preceded by zeroes. If it's more than 4 digits, you get the full number, but no leading zeroes.

Similarly, %d prints a signed int in decimal, and %u prints an unsigned int in decimal.

Not so similarly, %c prints a character and %s prints a string. For wide (Unicode) strings, prefixing with l (ell, or w): %lc and %ls.

Note: For the Unicode variants, such as wprintf and friends, %c and %s print wide strings. To force a narrow string, no matter which variant, use the %h size prefix, and to force a wide string, use the %l size prefix; e.g., %hs and %lc.

%p - pointer

The wrong way to print a pointer is to use %x. The right way is to use %p. It's portable to Win64, as well as to all other operating systems.

Everyone should know this one, but many don't.

%I64d, %I64u, %I64x - 64-bit integers

To print 64-bit numbers (__int64), use the I64 size prefix.

%Iu, %Id, %Ix - ULONG_PTR

ULONG_PTR, LONG_PTR, and DWORD_PTR are numeric types that are as wide as a pointer. In other words, they map to ULONG, LONG, and DWORD respectively on Win32, and ULONGLONG, LONGLONG, and ULONGLONG on Win64.

The I size prefix (capital-i, not lowercase-L) is what you need to print *LONG_PTR on Win32 and Win64.

%*d - runtime width specifier

If you want to calculate the width of a field at runtime, you can use %*. This says the next argument is the width, followed by whatever type you want to print.

For example, the following can be used to print a tree:

 void Tree::Print(Node* pNode, int level)
 {
     if (NULL != pNode)
     {
         Print(pNode->Left, level+1);
         printf("%*d%s"n", 2 * level, pNode->Key);
         Print(pNode->Right, level+1);
     }
 }

%.*s - print a substring

With a variable precision, you can print a substring, or print a non-NUL-terminated string, if you know its length. printf("%.*s"n", sublen, str) prints the first sublen characters of str.

[2005/7/19: fixed a typo in previous sentence (%.s -> %.*s). A little elaboration on the syntax: . in a printf format specification is followed by the precision. For strings, the precision specificies how many characters will be printed. A precision of * indicates that the precision is the next argument on the stack. If the precision is zero, then nothing is printed. If a string has a precision specification, its length is ignored.]

%.0d - print nothing for zero

I've occasionally found it useful to suppress output when a number is zero, and %.0d is the way to do it. (If you attempt to print a non-zero number with this zero-precision specifier, it will be printed.) Similarly, %.0s swallows a string.

%#x - print a leading 0x

If you want printf to automatically generate 0x before hex numbers, use %#x instead of %x. .

Security

Never use an inputted string as the format argument: printf(str). Instead, use printf("%s", str). The former is a stack smasher waiting to happen.

%n is dangerous and disabled by default in VS2005.

Don't use sprintf. Use the counted version, _snprintf or _vsnprintf instead. Better still, use the StrSafe.h functions, StringCchPrintf and StringCchVPrintf, to guarantee that your strings are NUL-terminated.

 

Note:

printf各项的意义介绍如下: 
1) 类型:类型字符用以表示输出数据的类型,其格式符和意义如下表所示: 
格式字符    意义 
 d         以十进制形式输出带符号整数(正数不输出符号) 
 o         以八进制形式输出无符号整数(不输出前缀0) 
x,X          以十六进制形式输出无符号整数(不输出前缀Ox) 
u           以十进制形式输出无符号整数 
f            以小数形式输出单、双精度实数 
e,E         以指数形式输出单、双精度实数 
g,G         以%f或%e中较短的输出宽度输出单、双精度实数 
c           输出单个字符 
s           输出字符串 
2) 标志:标志字符为-、+、#、空格四种,其意义下表所示: 
标 志       意义 
 -          结果左对齐,右边填空格 
 +          输出符号(正号或负号) 
空格        输出值为正时冠以空格,为负时冠以负号 
 #         对c,s,d,u类无影响;对o类,在输出时加前缀o;对x类,在输出时加前缀0x;对e,g,f 类

当结果有小数时才给出小数点 
3) 输出最小宽度: 用十进制整数来表示输出的最少位数。若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0。 
4) 精度: 精度格式符以“.”开头,后跟十进制整数。本项的意义是:如果输出数字,则表示小数的位数;如果输出的是字符,则表示输出字符的个数;若实际位数大于所定义的精度数,则截去超过的部分。 

5) 长度:长度格式符为h,l两种,h表示按短整型量输出,l表示按长整型量输出。

原文链接:点击打开链接

0 0