1. 程式人生 > 其它 >C語言格式化輸入輸出%hhd、%hhx等

C語言格式化輸入輸出%hhd、%hhx等

在學習小甲魚的課程過程中,要求計算128的5次方,並正確輸出。嘗試並查找了一週,找到一篇可以正確輸出的,抄錄下來作為記錄,便於以後使用。抄錄到最後發現是給C++用 的。不過大部分應該是一致的。先記下來吧。

printf sprint等:

格式字串的一般形式:[標誌][輸出最小寬度][.精度][長度]型別(其中方括號[]中的項為可選項。)

各項意義:

1)  型別:型別字元用以表示輸出資料的型別,其格式符和意義如下表所示:

格式字元                   意義

 d             以十進位制形式輸出帶符號整數(整數不輸出符號)

o                              以八進位制形式輸出無符號整數(不輸出字首o)

                   x,X                                以十六進位制形式輸出無符號證書(不輸出字首ox)

                   u                                   以十進位制形式輸出無符號整數

                   f                                    一小數形式輸出單、雙精度實數

                   e、E                                     以指數形式輸出單、雙精度實數

                   g、G                           以%f或%e中較短的輸出寬度輸出單、雙精度實數

                   c                                   輸出單個字元

2)  標誌:標識字元為-、+、#、空格四種,其意義如下表所示:

標誌                                               意義

-                       結果左對齊、右邊填空格

+                                   輸出符號(正號或負號)

空格                            輸出值為正時冠以空格,為負時冠以負號

#                                   對c、s、d、u類無影響;對o類,在輸出時加字首o;對x類,

在輸出時加字首ox;對e、g、f類當結果有小數時才給出小數點

3)  輸出最小寬度:用十進位制整數來表示輸出的最少位數。若實際位數多於定義的寬度,則按實際位數輸出,若實際位數少於定義的寬度則補以空格或0.

4)  精度:精度格式符以“.”開頭,後跟十進位制整數。本項的意義是:如果輸出數字,則表示小數的位數;如果輸出的是字元,則表示輸出字元的個數;若實際位數大於所定義的精度數,則截去超過的部分。

5)  長度:長度格式符為h,l兩種,h表示按短整型量輸出,l表示按長整型量輸出。

scanf

 格式字串的一般形式:%[*][輸入資料寬度][長度]型別(其中有方括號[]的項為人選項)

各種意義:

1)  型別:表示輸入資料的型別,其格式符和意義如下表所示。

格式字元                            意義

d                                   輸入十進位制整數

  • 輸入八進位制整數

x                                   輸入十六進位制整數

u                                   輸入無符號十進位制整數

f,e                             輸入實型數(用小數形式或指數形式)

c                                   輸入單個字元

s                                   輸入字串

2)  “*”符:用以表示該輸入項讀入後不賦予相應的變數,即跳過該輸入值。

  例:scanf(“%*d%d”,&a,&b);

  輸入:1 2 3    則a=1,2被跳過,b=3.

3)  寬度:用十進位制整數指定輸入的寬度(即字元數)。

   例1:scanf(“%5d”,&a);

輸入:12345678, 則a=12345,其餘部分被截去

例2:scanf(“%4d%4d”,&a,&b);

輸入:12345678   則a=1234,b=5678.

4)  長度:長度格式符為l和h,l表示輸入長整型資料(如%ld)和雙精度浮點數(如%lf)。h表示輸入短整型資料。

另外在使用scanf時還必須注意以下幾點:

1、  scanf函式中沒有精度控制,如:scanf(“%5.2f”,&a);是非法的。不能企圖用此語句輸入小數部分為2位的實數。

2、  在輸入多個數據數值時,若格式控制串中沒有非格式字元做輸入資料之間的間隔可用空格,TAB或回車做間隔。C語言在碰到空格、TAB,回車或非法資料(如對“%d”輸入“12A”時,A即為非法資料)時即認為該資料結束。

3、  在輸入字元資料時,若格式控制串中無非格式字元,則認為所有輸入的字元均為有效字元。

  例:scanf(“%c%c%c”,&a,&b,&c);

輸入:d e f   則a=’d’, b=’ ‘,c=’e’

輸入:def    則a=’d’,b=’e’,c=’f’.

        如果在格式控制中加入空格作為間隔,如:scanf(“%c %c %c”,&a,&b,&c);則輸入時各資料之間可加空格。

4、  如果格式控制串中有非格式字元則輸入時也要輸入該非格式字元。

例1:scanf(“%d,%d,%d”,&a,&b,&c);(其中用非格式符“,”做間隔符)

 輸入應為:5,6,7

例2:scanf(”a=%d,b=%d,c=%d”,&a,&b,&c);

 輸入應為:a=5,b=6,c=7

5、  如輸入的資料與輸出的型別不一致時,雖然編譯能夠通過,但結果將不正確。

附加:

%d    int              有符號10進位制整數

%u  unsigned int             無符號10進位制整數

%h  短型字首,後接d(10進位制整形)、x(16進位制整形)、o(8進位制整形)

%hd  short               有符號10進位制短整型

%hu  unsigned short      無符號10進位制短整型

%ld   long

%lu   unsigned long

%llu  unsigned long long

%0                              有符號8進位制整數

%x                                無符號的16進位制數字,並以小寫abcdef表示

%X                                無符號的16進位制數字,並以大寫ABCDEF表示

%f                                 輸入輸出為浮點型(%lf雙精度浮點型)

%c                                輸入輸出為單個字元

%s                                輸入輸出為字串

d,lx,ld,lu,這幾個都是輸出32位的

hd,hx,hu,這幾個都收輸出16位資料的

hhd,hhx,hhu,hho,這幾個都是輸出8位的10進位制、16進位制、無符號10進位制、8進位制

lld,ll,llu,llx,這幾個都是輸出64位的。

printf(“%llu”,…….)

  %llu 是64位無符號

  %llx才是64位16進位制數

下面列舉了Dev-C++下基本型別所佔位數和取值範圍:

符號屬性  長度屬性     基本型     所佔位數         取值範圍         輸入符舉例     輸出符舉例

  ---                   ---          char             8                -2^7~2^7-1            %c             %c,%d,%u

 signed     ---                char                    8           -2^7~2^7-1             %c             %c,%d,%u

unsigned           ---               char                    8           0~2^8-1                   %c             %c,%d,%u

[signed]             short         [int]                    16              -2^15~2^15-1           %hd

unsigned           short         [int]                    16              0~2^16-1                    %hu,%ho,%hx

[signed]             ---               int                       32              -2^31~2^31-1           %d

unsigned           ---               [int]                    32              0~2^32-1                    %u,%o,%x

[signed]             long           [int]                    32              -2^31~2^31-1           %ld

unsigned           long           [int]                    32              0~2^32-1                    %lu,%lo,%lx

[signed]             long long [int]                     64              -2^63~2^63-1           %l64d

unsigned      long long [int]                     64              0~2^64-1                    %l64u,%l64o,%l64x

---                        ---               float                   32              +/-3.40282e+038     %f,%e,%g

---                        ---               double               64              +/-1.79769e+308  %lf%le,%lg  %f,%e,%g

---                        long           double               96              +/-1.79769e+308     %Lf,%Le,%Lg

幾點說明:

1、  注意表中的每一行,代表一種基本型別。[]代表可以省略。

例如:char,signed char,unsigned char是三種互不相同的型別;

int,short,long也是三種互不相同的型別。

可以使用C++的函式過載特性進行驗證,如:

 void Func(char ch){}

 void Func(signed char ch){}

 void Func(unsigned char){}

是三個不同的函式。

2、  char/signed char/unsigned char型資料長度為1位元組;

char為有符號型,但與signed char 不同的型別。

注意:並不是所有的編譯器都是這樣處理,char型資料長度不一定為1位元組,char也不一定為有符號型。

3、  將char/signed char轉換為int時,會對最高符號位1進行擴充套件,從而造成運算問題。

所以,如果要處理的資料中存在位元組大於127的情況,使用unsigned char較為妥當。

程式中若涉及位運算,也應該使用unsigned型變數。

4、  char/signed char/unsigned char輸出時,使用格式符%c(按字元方式);

或使用%d,%u、%x/%X、%o,按整數方式輸出;

輸入時,應使用%c,若使用整數方式,Dev-C++會給出警告,不建議這樣使用。

5、  int的長度,是16位還是32位,與編譯器字長有關。

16位編譯器(如TC使用的編譯器)下,int為16位;32位編譯器(如VC使用的編譯器cl.exe)為32位。

6、  整形資料可以使用%d(有符號10進位制)、%o(無符號8進位制)或%x/%X(無符號16進位制)方式輸入輸出。

而格式符%u,表示unsigned,即無符號10進位制方式。

7、  整形字首h表示short ,l表示long。

輸入輸出short/unsigned short時,不建議直接使用int的格式符%d/%u等,要加字首h。

這個習慣性錯誤,來源於TC.TC下,int的長度和預設符號屬性,都與short一致,於是就把這兩種型別當成是相同的,都用int方式進行輸入輸出。

8、  關於long long型別的輸入輸出:

“%lld”和“%llu”是linux下gcc/gcc+用於long long int型別(64 bits)型別的格式符。

而”%l64d”和“%l64u”則是Microsoft VC++庫用於輸入輸出_int64型別的格式說明。Dev-C++使用的編譯器是Mingw32,Mingw32是X86-win32 gcc子專案之一,編譯器核心還是linux下的gcc。

進行函式引數型別檢查的是在編譯階段,gcc編譯器對格式字串進行檢查,顯然它不認得”l64d”所以將給出警告”unknown conversion type character ‘I’ informat”。對於“%lld”和“%llu”,gcc理所當然的接受了。

Mingw32在編譯期間使用gcc的規則檢查語法,在連線和執行時使用的卻是Microsoft庫。這個庫裡的printf和scanf函式當然不認識linux gcc下“%lld”和“%llu”,但對“%64d”和“%l64u”,它則是樂意接受,並能正常工作的。

9、  浮點型資料輸入時可使用%f、%e、%E或%g、%G,scanf會根據輸入資料形式,自動處理。輸出時可使用%f(普通方式)、%e、%E(指數方式)或%g、%G(自動選擇)。

10、              浮點引數壓棧的規則:float(4位元組)型別擴充套件成double(8位元組)入棧。

所以在輸入時,需要區分float(%f)與double(%lf),而在輸出時,用%f即可、

printf函式將按照double型 規則對壓入堆疊的float(已擴充套件成double)和double型資料進行輸出。如果在輸出時指定%lf格式符,gcc、Mingw32編譯器將給出一個警告。

11、              Dev-C++(gcc、MIngw32)可以選擇float的長度,是否與double一致。

12、              字首L表示long(double)。

雖然long double比double長4個位元組,但是表示的數值範圍卻是一樣的。

long double型別的長度、精度及表示範圍與所使用 編譯器、作業系統有關。