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型別的長度、精度及表示範圍與所使用 編譯器、作業系統有關。