1. 程式人生 > 其它 >C語言_格式化輸入輸出

C語言_格式化輸入輸出

C語言_格式化輸入輸出

我們知道在最開始輸入輸出的printf和scanf裡可以用百分號跟上一個字母d 說明要整數的型別,%f說明要以浮點數輸出

  • printf()
  • %[flags][width][.prec][hlL]type
  • scanf()
  • %[flag]type

我們知道在最開始輸入輸出的printf和scanf裡可以用百分號跟上一個字母d 說明要整數的型別,%f說明要以浮點數輸出,殊不知這其中還有很多數值…

  • %[flags][width][.prec][hlL]type
type含義
-左對齊
+在前面放+或-
(space)正數留空
00填充

我們來試一下這樣的事情,如下 做一個簡單的模型

    printf
("%9d\n",123); printf("%-9d\n",123);

第一個%9d表示後面數字的輸出佔據九個字元的空間,並且是右對齊的,所以前面留出來空格
而第二個帶-號表示是左對齊

“+” 號含義是後面要跟上+號或者- 號,我們試試

  printf("%+9d\n",123);
  printf("%+-9d\n",123);

執行結果:
在這裡插入圖片描述
果不其然 ,前面加上了+號

printf("%+9d\n",-123);
printf("%+-9d\n",-123
);

執行結果:
在這裡插入圖片描述
這樣都沒什麼問題 其實如果不要第二行這個+ 號,編譯器也同樣會加上-號的,那麼我們加0呢

printf("%09d\n",123);
printf("%0-9d\n",-123);

執行結果:
在這裡插入圖片描述
可以看到右對齊的前面補了零,而左對齊的-123是不能補零的,總不能向後填零吧

width或prec含義
number最小字元數
*下一個引數是字元數
.number小數點後的位數
.*下一個引數是小數點後的位數
printf("%9.2f\n",123.0);

執行結果:
在這裡插入圖片描述
這裡注意一下, 小數點前面的9指的是整個數字包括小數點以及小數點後面的0,總和佔9個字元 而不是小數點前面佔9個字元,.2f 表示精確到小數點後倆位

那麼那個*又是表達什麼意思呢

printf("%*d\n",5,123);
printf("%9.2f\n",123.0);

執行結果:
在這裡插入圖片描述
可以看到第一行後面的形參多了一個,就好比把5 這個值替換了*,而後面的123是用來滿足這個%d的,原本要填入%後面的數字,現在可以替換出來,而一旦變成後面的引數,那他就可以是一個變量了,而不是常量,給我們的程式碼格式帶來了很大的靈活性

型別修飾含義
hh單個位元組
hshort
llong
lllong long
Llong double
type作用
i或dint
uunsigned int
a或A十進位制浮點數
0八進位制
cchar
x十六進位制
s字串
X字母大寫的十六進位制
p指標
f或Ffloat
n讀寫/寫入的個數
e或E指數

暫時列出來,有些學到後面會慢慢遇見 ,不過這裡要講一下n這個type

int num;
printf("%dsos%n\n",12345,&num);

執行結果:
在這裡插入圖片描述
字串後面的第一個引數12345,滿足了%d,後面的sos也輸出了, %n說明符輸出有效字元數量,然後把個數傳入後面的指標裡。

  • scanf
  • %[flag]tpye
flag含義
*跳過
數字最大字元數
hhchar
hshort
llong ldouble
lllong long
Llong double

有一點我們需要注意,我們要確保轉換說明的數量、型別、和後面的引數的數量、型別一樣,例如下面的語句中有倆個%d轉換說明,說明後面還有倆個引數

printf("%d 個蘋果 %d 元\n",number,money);

後面的確有倆個引數 用來滿足倆個%d轉換說明
現在C語言通過函式原型機制檢查函式呼叫時引數的個書和型別是否正確,但是這對printf()和scanf()函式不起作用,原因是因為這個倆個函式的引數個數可變,如下:

int a=4;
int b=6;
float x=3.14f;   
float y=8.0f;
printf("%d\n",a,b);   //引數過多
printf("%d %d\n",a);  //引數過少
printf("%d %d\n",x,y); //轉換說明型別不匹配

執行結果:
在這裡插入圖片描述
用%d顯示float型別的值,這個值不會被轉成int型別,在不同的平臺下面,執行結果也會導致不同

注意:通常3.14和8.0都會被編譯器儲存在64位的double型別中,使用雙精度進行乘法運算,然後將乘積截斷成float的快讀,這樣雖然計算精度更高,但無疑會減慢執行速度,我們不是在做非常精確的計算 ,所以不用那麼精準,可以在浮點數後面加上F或f字尾就可以覆蓋編譯器預設的是指,編譯器會將浮點型別常量看作float型別
沒有後綴的浮點常量是double型別。
很顯然這都不是我們想要的結果,所有的編譯器都能編譯並且執行這個程式,但是大部分的編譯器都會給予警告,的確,有些編譯器會捕捉到這類問題,但是c標準沒有對此多要求,所以,計算機在執行時可能不會捕捉到這類錯誤,如果程式正常執行,很難察覺出來,大概只有程式沒有打印出你所期望的或者意想不到的值的時候,你才會去檢查prinf()函式中的引數型別和個數是否正確