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 thefull 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 theprecision. 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 theStrSafe.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表示按長整型量輸出。
最後,總是有人碰到了問題如下:
將DWORD變量格式化到CString中來,但結果顯示不正確。
DWORD a=399811571;
CString str;
str.Format("%d",a);
Format裏面用"%ld"也不行 ,其結果字符串爲 到符號的數字字符串。
正確的格式爲:str.Format("%u",a); 之前碰到過不知道怎麼辦,後來想起來了。^_^