天天看點

NSLog 是不是Xcode總是報告NSLog格式輸出不對? String Format Specifiers

在Objective-C中,NSLog相當于C語言中的printf,常用于文字輸出。

  NSLog定義在NSObjCRuntime.h中,如下所示:

  void NSLog(NSString *format, …);

  基本上,NSLog很像printf,同樣會在console中輸出顯示結果。不同的是,傳遞進去的格式化字元是NSString的對象,而不是char *這種字元串指針。

  NSLog可以如下面的方法使用:

  NSLog (@"this is a test");

  NSLog (@"string is :%@", string);

  NSLog (@"x=%d, y=%d", 10, 20);

  但是下面的寫法是不行的:

  int i = 12345;

  NSLog( @"%@", i );

  原因是, %@需要顯示對象,而int i明顯不是一個對象,要想正确顯示,要寫成:

  NSLog( @"%d", i );

  NSLog的格式如下所示:

  %@ 對象

  %d, %i 整數%u 無符整形%f 浮點/雙字%x, %X 二進制整數%o 八進制整數%zu size_t%p 指針%e 浮點/雙字 (科學計算)%g 浮點/雙字 %s C 字元串%.*s Pascal字元串%c 字元%C unichar%lld 64位長整數(long long)%llu 無符64位長整數%Lf 64位雙字

Yes, 

warning: Format String Issue: Conversion specifies type 'int' but the argument has type 'long'

This article summarizes the format specifiers supported by string formatting methods and functions.

<a></a>

The format specifiers supported by the <code>NSString</code> formatting

positional specifiers such as <code>%1$@ %2$s</code>. For

Table 1  Format

specifiers supported by the <code>NSString</code> formatting

methods and CFString formatting functions

Specifier

Description

<code>%@</code>

Objective-C object, printed as the string returned by <code>descriptionWithLocale:</code> if

available, or <code>description</code> otherwise. Also works with<code>CFTypeRef</code> objects,

returning the result of the <code>CFCopyDescription</code> function.

<code>%%</code>

<code>'%'</code> character

<code>%d</code>, <code>%D</code>,<code>%i</code>

Signed 32-bit integer (<code>int</code>)

<code>%u</code>, <code>%U</code>

Unsigned 32-bit integer (<code>unsigned int</code>)

<code>%hi</code>

Signed 16-bit integer (<code>short</code>)

<code>%hu</code>

Unsigned 16-bit integer (<code>unsigned short</code>)

<code>%qi</code>

Signed 64-bit integer (<code>long long</code>)

<code>%qu</code>

Unsigned 64-bit integer (<code>unsigned long long</code>)

<code>%x</code>

Unsigned 32-bit integer (<code>unsigned int</code>), printed in hexadecimal

using the digits 0–9 and lowercase a–f

<code>%X</code>

using the digits 0–9 and uppercase A–F

<code>%qx</code>

Unsigned 64-bit integer (<code>unsigned long long</code>), printed in hexadecimal

<code>%qX</code>

<code>%o</code>, <code>%O</code>

Unsigned 32-bit integer (<code>unsigned int</code>), printed in octal

<code>%f</code>

64-bit floating-point number (<code>double</code>)

<code>%e</code>

64-bit floating-point number (<code>double</code>), printed in scientific notation

using a lowercase e to introduce the exponent

<code>%E</code>

using an uppercase E to introduce the exponent

<code>%g</code>

64-bit floating-point number (<code>double</code>), printed in the style of <code>%e</code> if

the exponent is less than –4 or greater than or equal to the precision, in the style of <code>%f</code> otherwise

<code>%G</code>

64-bit floating-point number (<code>double</code>), printed in the style of <code>%E</code> if

<code>%c</code>

8-bit unsigned character (<code>unsigned char</code>), printed by <code>NSLog()</code> as

an ASCII character, or, if not an ASCII character, in the octal format <code>\\ddd</code> or

the Unicode hexadecimal format <code>\\udddd</code>, where <code>d</code> is

a digit

<code>%C</code>

16-bit Unicode character (<code>unichar</code>), printed by <code>NSLog()</code> as

<code>%s</code>

Null-terminated array of 8-bit unsigned characters. <code>%s</code> interprets

its input in the system encoding rather than, for example, UTF-8.

<code>%S</code>

Null-terminated array of 16-bit Unicode characters

<code>%p</code>

Void pointer (<code>void *</code>), printed in hexadecimal with the digits

0–9 and lowercase a–f, with a leading <code>0x</code>

<code>%L</code>

Length modifier specifying that a following <code>a</code>, <code>A</code>, <code>e</code>, <code>E</code>, <code>f</code>, <code>F</code>, <code>g</code>,

or <code>G</code> conversion specifier applies to a <code>long double</code> argument

<code>%a</code>

with a leading <code>0x</code> and one hexadecimal digit before the decimal

point using a lowercase <code>p</code> to introduce the exponent

<code>%A</code>

with a leading <code>0X</code> and one hexadecimal digit before the decimal

point using a uppercase <code>P</code> to introduce the exponent

<code>%F</code>

64-bit floating-point number (<code>double</code>), printed in decimal notation

<code>%z</code>

Length modifier specifying that a following <code>d</code>, <code>i</code>, <code>o</code>, <code>u</code>, <code>x</code>,

or <code>X</code> conversion specifier applies to a <code>size_t</code> or

the corresponding signed integer type argument

<code>%t</code>

or <code>X</code> conversion specifier applies to a <code>ptrdiff_t</code> or

the corresponding unsigned integer type argument

<code>%j</code>

or <code>X</code> conversion specifier applies to a <code>intmax_t</code> or <code>uintmax_t</code> argument

Mac OS X uses several data types—<code>NSInteger</code>, <code>NSUInteger</code>,<code>CGFloat</code>,

and <code>CFIndex</code>—to provide a consistent means of

representing values in 32- and 64-bit environments. In a 32-bit environment, <code>NSInteger</code> and <code>NSUInteger</code> are

defined as <code>int</code> and <code>unsigned int</code>, respectively. In 64-bit environments, <code>NSInteger</code>and <code>NSUInteger</code> are

defined as <code>long</code> and <code>unsigned long</code>, respectively. To avoid the need to use different printf-style type specifiers depending on the platform, you can use the specifiers shown in Table

2. Note that in some cases you may have to cast the value.

Table 2  Format

specifiers for data types

Type

Format specifier

Considerations

<code>NSInteger</code>

<code>%ld</code> or <code>%lx</code>

Cast the value to <code>long</code>

<code>NSUInteger</code>

<code>%lu</code> or <code>%lx</code>

Cast the value to <code>unsigned long</code>

<code>CGFloat</code>

<code>%f</code> or <code>%g</code>

<code>%f</code> works for floats and doubles when formatting; but see below

warning when scanning

<code>CFIndex</code>

The same as <code>NSInteger</code>

pointer

<code>%p</code> adds <code>0x</code> to

the beginning of the output. If you don't want that, use <code>%lx</code> and

cast to <code>long</code>.

<code>long long</code>

<code>%lld</code> or <code>%llx</code>

<code>long long</code> is 64-bit on both 32- and 64-bit platforms

<code>unsigned long long</code>

<code>%llu</code> or <code>%llx</code>

<code>unsigned long long</code> is 64-bit on both 32- and 64-bit platforms

The following example illustrates the use of <code>%ld</code> to

format an <code>NSInteger</code> and the use of a cast.

In addition to the considerations mentioned in Table 2, there is one extra case with scanning:

you must distinguish the types for <code>float</code> and <code>double</code>.

You should use <code>%f</code> for float, <code>%lf</code> for

double. If you need to use <code>scanf</code> (or a variant

thereof) with <code>CGFloat</code>, switch to <code>double</code> instead,

and copy the <code>double</code> to<code>CGFloat</code>.

It is important to remember that <code>%lf</code> does not

represent <code>CGFloat</code> correctly on either 32- or

64-bit platforms. This is unlike <code>%ld</code>, which works

for <code>long</code> in all cases.

繼續閱讀