Linux中國

如何使用 printf 來格式化輸出

當我開始學習 Unix 時,我很早就接觸到了 echo 命令。同樣,我最初的 Python 課程也涉及到了 print 函數。再想起學習 C++ 和 Java 時學到 coutsystemout。似乎每種語言都驕傲地宣稱擁有一種方便的單行輸出方法,並生怕這種方式要過時一樣宣傳它。

但是當我翻開中級教程的第一頁後,我遇到了 printf,一個晦澀難懂的、神秘莫測的,又出奇靈活的函數。本文一反向初學者隱藏 printf 這個令人費解的傳統,旨在介紹這個不起眼的 printf 函數,並解釋如何在幾乎所有語言中使用它。

printf 簡史

術語 printf 代表「 格式化列印 print formatted 」,它可能最早出現 Algol 68 編程語言中。自從它被納入到 C 語言後,printf 已經在 C++、Java、Bash、PHP 中一次次重新實現,並且很可能在你最喜歡的 「後 C」 語言中再次出現。

顯然,它很受歡迎,但很多人認為它的語法很複雜,尤其是與 echoprintcout 等替代的函數相比尤為明顯。例如,這是在 Bash 中的一個簡單的 echo 語句:

$ echo hello
hello
$

這是在 Bash 中使用 printf 得到同樣結果:

$ printf "%sn" hello
hello
$

但是所增加的複雜性反而讓你擁有很多功能,這是為什麼 printf 值得學習的確切原因。

printf 輸出

printf 背後的基本思想是:它能夠基於與內容分離的樣式信息來格式化輸出。例如,這裡是 printf 認可的視作特殊字元的特定序列集合。你喜歡的語言可能會有或多或少的序列,但是通常包含:

  • n: 新行
  • r: 回車換行
  • t: 水平製表符
  • NNN: 一個包含一個到三個數字,使用八進位值表示的特殊位元組

例如:

$ printf "t123105124110n"
     SETH
$

在這個 Bash 示例中, printf 渲染一個製表符後,然後是分配給四個八進位值字元串的 ASCII 字元,並以一個生成一個新行(n)的控制序列結束。

如果同樣使用 echo 來輸出會產生更多的字元:

$ echo "t123105124110n"
t123105124110n
$

使用 Python 的 print 函數來完成同樣的任務,你會發現 Python 的 print 命令比你想像的要強大:

>>> print("t123n")
        S

>>>

顯然,Python 的 print 包含傳統的 printf 特性以及簡單的 echocout 的特性。

不過,這些示例包括的只是文字字元,儘管在某些情況下它們也很有用,但它們可能是 printf 最不重要的部分。printf 的真正的威力在於格式化說明。

使用 printf 格式化輸出

格式化說明符是以一個百分號(%)開頭的字元。

常見的格式化說明符包括:

  • %s: 字元串
  • %d: 數字
  • %f: 浮點數字
  • %o: 一個八進位的數字

這些格式化說明符是 printf 語句的佔位符,你可以使用一個在其它地方提供的值來替換你的 printf 語句中的佔位符。這些值在哪裡提供取決於你使用的語言和它的語法,這裡有一個簡單的 Java 例子:

string var="hellon";
system.out.printf("%s", var);

把這個代碼包裹在適當的樣板文件中,在執行後,將呈現:

$ ./example
hello
$

但是,當一個變數的內容更改時,有意思的地方就來了。假設你想基於不斷增加的數字來更新輸出:

#include <stdio.h>

int main() {
  int var=0;
  while ( var < 100) {
    var++;
  printf("Processing is %d% finished.n", var);
  }
  return 0;
}

編譯並運行:

Processing is 1% finished.
[...]
Processing is 100% finished.

注意,在代碼中的兩個 % 將被解析為一個列印出來的 % 符號。

使用 printf 限制小數位數

數字也可以是很複雜,printf 提供很多格式化選項。你可以對浮點數使用 %f 限制列印出多少個小數位。通過把一個點(.)和一個限制的數放置在百分符號和 f 之間, 你可以告訴 printf 列印多少位小數。這是一個簡單的用 Bash 寫的簡練示例:

$ printf "%.2fn" 3.141519
3.14
$

類似的語法也適用於其它的語言。這裡是一個 C 語言的示例:

#include <math.h>
#include <stdio.h>

int main() {
  fprintf(stdout, "%.2fn", 4 * atan(1.0));
  return 0;
}

對於三位小數,使用 .3f ,依次類推。

使用 printf 來在數字上添加逗號

因為位數大的數字很難解讀,所以通常使用一個逗號來斷開大的數字。你可以在百分號和 d 之間放置一個撇號(&apos;),讓 printf 根據需要添加逗號:

$ printf "%&apos;dn" 1024
1,024
$ printf "%&apos;dn" 1024601
1,024,601
$

使用 printf 來添加前綴零

printf 的另一個常用的用法是對文件名稱中的數字強制實行一種特定的格式。例如,如果你在一台計算機上有 10 個按順序排列的文件,計算機可能會把 10.jpg 排在 1.jpg 之前,這可能不是你的本意。當你以編程的方式寫一個到文件時,你可以使用 printf 來用前綴為 0 的字元形成文件名稱。這是一個簡單的用 Bash 寫的簡練示例:

$ printf "%03d.jpgn" {1..10}
001.jpg
002.jpg
[...]
010.jpg

注意:每個數字最多使用 3 位數字。

使用 printf

正如這些 printf 示例所顯示,包括控制字元,尤其是 n ,可能會冗長,並且語法相對複雜。這就是為什麼開發像 echocout 之類的快捷方式的原因。不過,如果你時不時地使用 printf ,你就會習慣於這種語法,並且它也會變成你的習慣。我不認為 printf 有任何理由成為你在日常活動中列印時的首選,但是它是一個很好的工具,當你需要它時,它不會拖累你。

花一些時間學習你所選擇語言中的 printf,並且當你需要時就使用它。它是一個強有力的工具,你不會後悔隨時可用的工具。

via: https://opensource.com/article/20/8/printf

作者:Seth Kenlon 選題:lujun9972 譯者:robsean 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國