mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-25 23:11:02 +08:00
commit
a7ca689c24
@ -1,222 +0,0 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to use printf to format output)
|
||||
[#]: via: (https://opensource.com/article/20/8/printf)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
How to use printf to format output
|
||||
======
|
||||
Get to know printf, a mysterious, flexible, and feature-rich alternative
|
||||
to echo, print, and cout.
|
||||
![Person drinking a hot drink at the computer][1]
|
||||
|
||||
When I started learning Unix, I was introduced to the `echo` command pretty early in the process. Likewise, my initial [Python][2] lesson involved the `print` function. Picking up C++ and [Java][2] introduced me to `cout` and `systemout`. It seemed every language proudly had a convenient one-line method of producing output and advertised it like it was going out of style.
|
||||
|
||||
But once I turned the first page of intermediate lessons, I met `printf`, a cryptic, mysterious, and surprisingly flexible function. In going against the puzzling tradition of hiding `printf` from beginners, this article aims to introduce to the world the humble `printf` function and explain how it can be used in nearly any language.
|
||||
|
||||
### A brief history of printf
|
||||
|
||||
The term `printf` stands for "print formatted" and may have first appeared in the [Algol 68][3] programming language. Since its inclusion in C, `printf` has been reimplemented in C++, Java, Bash, PHP, and quite probably in whatever your favorite (post-C) language happens to be.
|
||||
|
||||
It's clearly popular, and yet many people seem to regard its syntax to be complex, especially compared to alternatives such as `echo` or `print` or `cout`. For example, here's a simple echo statement in Bash:
|
||||
|
||||
|
||||
```
|
||||
$ echo hello
|
||||
hello
|
||||
$
|
||||
```
|
||||
|
||||
Here's the same result using `printf` in Bash:
|
||||
|
||||
|
||||
```
|
||||
$ printf "%s\n" hello
|
||||
hello
|
||||
$
|
||||
```
|
||||
|
||||
But you get a lot of features for that added complexity, and that's exactly why `printf` is well worth learning.
|
||||
|
||||
### printf output
|
||||
|
||||
The main concept behind `printf` is its ability to format its output based on style information _separate_ from the content. For instance, there is a collection of special sequences that `printf` recognizes as special characters. Your favorite language may have greater or fewer sequences, but common ones include:
|
||||
|
||||
* `\n`: New line
|
||||
* `\r`: Carriage return
|
||||
* `\t`: Horizontal tab
|
||||
* `\NNN`: A specific byte with an octal value containing one to three digits
|
||||
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
```
|
||||
$ printf "\t\123\105\124\110\n"
|
||||
SETH
|
||||
$
|
||||
```
|
||||
|
||||
In this Bash example, `printf` renders a tab character followed by the ASCII characters assigned to a string of four octal values. This is terminated with the control sequence to produce a new line (`\n`).
|
||||
|
||||
Attempting the same thing with `echo` produces something a little more literal:
|
||||
|
||||
|
||||
```
|
||||
$ printf "\t\123\105\124\110\n"
|
||||
\t\123\105\124\110\n
|
||||
$
|
||||
```
|
||||
|
||||
Using Python's `print` function for the same task reveals there's more to Python's `print` command than you might expect:
|
||||
|
||||
|
||||
```
|
||||
>>> print("\t\123\n")
|
||||
S
|
||||
|
||||
>>>
|
||||
```
|
||||
|
||||
Obviously, Python's `print` incorporates traditional `printf` features as well as the features of a simple `echo` or `cout`.
|
||||
|
||||
These examples contain nothing more than literal characters, though, and while they're useful in some situations, they're probably the least significant thing about `printf`. The true power of `printf` lies in format specification.
|
||||
|
||||
### Format output with printf
|
||||
|
||||
Format specifiers are characters preceded by a percent sign (`%`).
|
||||
Common ones include:
|
||||
|
||||
* `%s`: String
|
||||
* `%d`: Digit
|
||||
* `%f`: Floating-point number
|
||||
* `%o`: A number in octal
|
||||
|
||||
|
||||
|
||||
These are placeholders in a `printf` statement, which you can replace with a value you provide somewhere else in your `printf` statement. Where these values are provided depends on the language you're using and its syntax, but here's a simple example in Java:
|
||||
|
||||
|
||||
```
|
||||
string var="hello\n";
|
||||
system.out.printf("%s", var);
|
||||
```
|
||||
|
||||
This, wrapped in appropriate boilerplate code and executed, renders:
|
||||
|
||||
|
||||
```
|
||||
$ ./example
|
||||
hello
|
||||
$
|
||||
```
|
||||
|
||||
It gets even more interesting, though, when the content of a variable changes. Suppose you want to update your output based on an ever-increasing number:
|
||||
|
||||
|
||||
```
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
int var=0;
|
||||
while ( var < 100) {
|
||||
var++;
|
||||
printf("Processing is %d% finished.\n", var);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Compiled and run:
|
||||
|
||||
|
||||
```
|
||||
Processing is 1% finished.
|
||||
[...]
|
||||
Processing is 100% finished.
|
||||
```
|
||||
|
||||
Notice that the double `%` in the code resolves to a single printed `%` symbol.
|
||||
|
||||
### Limiting decimal places with printf
|
||||
|
||||
Numbers can get complex, and `printf` offers many formatting options. You can limit how many decimal places are printed using the `%f` for floating-point numbers. By placing a dot (`.`) along with a limiter number between the percent sign and the `f`, you tell `printf` how many decimals to render. Here's a simple example written in Bash for brevity:
|
||||
|
||||
|
||||
```
|
||||
$ printf "%.2f\n" 3.141519
|
||||
3.14
|
||||
$
|
||||
```
|
||||
|
||||
Similar syntax applies to other languages. Here's an example in C:
|
||||
|
||||
|
||||
```
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
[fprintf][4](stdout, "%.2f\n", 4 * [atan][5](1.0));
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
For three decimal places, use `.3f`, and so on.
|
||||
|
||||
### Adding commas to a number with printf
|
||||
|
||||
Since big numbers can be difficult to parse, it's common to break them up with a comma. You can have `printf` add commas as needed by placing an apostrophe (`'`) between the percent sign and the `d`:
|
||||
|
||||
|
||||
```
|
||||
$ printf "%'d\n" 1024
|
||||
1,024
|
||||
$ printf "%'d\n" 1024601
|
||||
1,024,601
|
||||
$
|
||||
```
|
||||
|
||||
### Add leading zeros with printf
|
||||
|
||||
Another common use for `printf` is to impose a specific format upon numbers in file names. For instance, if you have 10 sequential files on a computer, the computer may sort `10.jpg` before `1.jpg`, which is probably not your intent. When writing to a file programmatically, you can use `printf` to form the file name with leading zero characters. Here's an example in Bash for brevity:
|
||||
|
||||
|
||||
```
|
||||
$ printf "%03d.jpg\n" {1..10}
|
||||
001.jpg
|
||||
002.jpg
|
||||
[...]
|
||||
010.jpg
|
||||
```
|
||||
|
||||
Notice that a maximum of 3 places are used in each number.
|
||||
|
||||
### Using printf
|
||||
|
||||
As you can tell from these `printf` examples, including control characters, especially `\n`, can be tedious, and the syntax is relatively complex. This is the reason shortcuts like `echo` and `cout` were developed. However, if you use `printf` every now and again, you'll get used to the syntax, and it will become second nature. I don't see any reason `printf` should be your _first_ choice for printing statements during everyday activities, but it's a great tool to be comfortable enough with that it won't slow you down when you need it.
|
||||
|
||||
Take some time to learn `printf` in your language of choice, and use it when you need it. It's a powerful tool you won't regret having at your fingertips.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/8/printf
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hot drink at the computer)
|
||||
[2]: https://opensource.com/resources/python
|
||||
[3]: https://opensource.com/article/20/6/algol68
|
||||
[4]: http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
|
||||
[5]: http://www.opengroup.org/onlinepubs/009695399/functions/atan.html
|
222
translated/tech/20200813 How to use printf to format output.md
Normal file
222
translated/tech/20200813 How to use printf to format output.md
Normal file
@ -0,0 +1,222 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (robsean)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (How to use printf to format output)
|
||||
[#]: via: (https://opensource.com/article/20/8/printf)
|
||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||
|
||||
如何使用 printf 来格式化输出
|
||||
======
|
||||
开始了解 printf ,一个神秘的,灵活的,和功能丰满的可替换 echo, print,和 cout 的函数。
|
||||
|
||||
![在计算机前喝热饮料][1]
|
||||
|
||||
当我开始学习 Unix 时,在很早的过程中,我就被介绍尝试 `echo` 命令。同样在很早的过程中,我最初的 [Python][2] 课程介绍 `print` 函数。拾起 C++ 和 [Java][2] 介绍给我的 `cout` 和 `systemout`。似乎每种语言都很自豪地有一个简单的一行产生输出的方法,并且被宣告这种方法的样式过时了。
|
||||
|
||||
但是在我翻开中级教程的第一页后,我遇到了 `printf`,一个晦涩难懂的,诡秘的,和出奇灵活的函数。违背了向初学者隐藏 `printf` 这个令人迷惑的传统,这篇文章旨在介绍不起眼的 `printf` 函数,并解释如何在近乎任意语言中使用它。
|
||||
|
||||
### printf 简史
|
||||
|
||||
术语 `printf` 代表 "格式化输出",可能在 [Algol 68][3] 编程语言中首次出现。自从它包含在 C 中,`printf` 已经在 C++,Java,Bash,PHP 中被重新实施,并且很可能在发生在你最喜欢的 ( C 衍生) 语言中。
|
||||
|
||||
它显然是很受欢迎,并且还有很多人认为它的语法很复杂,尤其是与 `echo` 或 `print` 或 `cout` 等可替代函数相比尤为明显。例如,在 Bash 中有一个简单的 echo 语句:
|
||||
|
||||
|
||||
```
|
||||
$ echo hello
|
||||
hello
|
||||
$
|
||||
```
|
||||
|
||||
在 Bash 中使用 `printf` 有相同的结果:
|
||||
|
||||
|
||||
```
|
||||
$ printf "%s\n" hello
|
||||
hello
|
||||
$
|
||||
```
|
||||
|
||||
但是所增加的复杂性反而让你拥有很多功能,这是为什么 `printf` 值得学习的确切原因。
|
||||
|
||||
### printf 输出
|
||||
|
||||
在 `printf` 背后的主要概念是:它能够基于来自内容的 _单独的_ 样式信息来格式化输出。例如,这里是 `printf` 认可的作为特殊字符的排列顺序的收藏品。你最喜欢的语言可能有更多一些或更少一些排列顺序,但是通常包含:
|
||||
|
||||
* `\n`: 新行
|
||||
* `\r`: 换行
|
||||
* `\t`: 水平制表符
|
||||
* `\NNN`: 一个使用八进制值的包含一个到三个数字的特殊字节
|
||||
|
||||
|
||||
|
||||
例如:
|
||||
|
||||
|
||||
```
|
||||
$ printf "\t\123\105\124\110\n"
|
||||
SETH
|
||||
$
|
||||
```
|
||||
|
||||
在这个 Bash 示例中, `printf` 在 ASCII 分配到四个八进制值的字符串的字符后渲染一个制表符。使用控制排列顺序来中止行,并生成一个新行 (`\n`) 。
|
||||
|
||||
使用 `echo` 来尝试相同的东西来生成一点儿完完全全的东西:
|
||||
|
||||
|
||||
```
|
||||
$ printf "\t\123\105\124\110\n"
|
||||
\t\123\105\124\110\n
|
||||
$
|
||||
```
|
||||
|
||||
对于相同是任务,使用 Python 的 `print` 函数,你会发现 Python 的 `print` 命令有你可以期待的更多的东西:
|
||||
|
||||
|
||||
```
|
||||
>>> print("\t\123\n")
|
||||
S
|
||||
|
||||
>>>
|
||||
```
|
||||
|
||||
显然,Python 的 `print` 包含传统的 `printf` 功能以及简单的 `echo` 或 `cout` 的功能。
|
||||
|
||||
不过,这些示例只包括字面意义上的字符,虽然在一些情况下它们也很有用,它们可能是 `printf` 最不重要的部分。`printf` 的真正的威力在于格式化规范。
|
||||
|
||||
### 使用 printf 格式化输出
|
||||
|
||||
格式化说明符是以一个百分号(`%`)开头的字符。
|
||||
常见的格式化说明符包括:
|
||||
|
||||
* `%s`: 字符串
|
||||
* `%d`: 数字
|
||||
* `%f`: 浮点数字
|
||||
* `%o`: 一个八进制的数字
|
||||
|
||||
|
||||
|
||||
这些格式化说明符在一个 `printf` 语句中是占位符,在你的`printf`语句中,你可以使用一个你在其它地方中提供的值来替换。但是这些提供的值取决于你正在使用的语言及其语法,这里是一个简单的 Java 示例:
|
||||
|
||||
|
||||
```
|
||||
string var="hello\n";
|
||||
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 "%.2f\n" 3.141519
|
||||
3.14
|
||||
$
|
||||
```
|
||||
|
||||
类似的语法也适用于其它的语言。这里是一个 C 语言的示例:
|
||||
|
||||
|
||||
```
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
fprintf(stdout, "%.2f\n", 4 * atan(1.0));
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
对于三位小数,使用 `.3f` ,依次类推。
|
||||
|
||||
### 使用 printf 来在数字上添加逗号
|
||||
|
||||
因为位数大的数字很难分解,所以通常使用一个逗号来断开大的数字。你可以根据需要在由 `printf` 组成的百分号和`d` 之间放置一个撇号(`'`) :
|
||||
|
||||
|
||||
```
|
||||
$ printf "%'d\n" 1024
|
||||
1,024
|
||||
$ printf "%'d\n" 1024601
|
||||
1,024,601
|
||||
$
|
||||
```
|
||||
|
||||
### 使用 printf 来添加前缀零
|
||||
|
||||
Another common use for `printf` 的另一个常用的用法是对文件名称中的数字强制实行一种特定的格式。例如,如果你在一台计算机上有 10 个按顺序排列的文件,该计算机可能会把 `10.jpg` 排在before `1.jpg` 之前,这可能不是你的本意。当你以编程的方式写一个到文件时,你可以使用 `printf` 来用前缀为0的字符来构成文件名称。这是一个简单的用 Bash 写的简练示例:
|
||||
|
||||
|
||||
```
|
||||
$ printf "%03d.jpg\n" {1..10}
|
||||
001.jpg
|
||||
002.jpg
|
||||
[...]
|
||||
010.jpg
|
||||
```
|
||||
|
||||
注意:每个数字最多使用 3 位数字。
|
||||
|
||||
### 使用 printf
|
||||
|
||||
正如这些 `printf` 示例所显示,包括控制字符,尤其是 `\n` ,可能会冗长,并且语法是相当地复杂。这就是为什么开发像 `echo` 和 `cout` 之类的快捷方式的原因。不过,如果你是不是地使用 `printf` ,你将会习惯于语法,并且它也将变成你的后天本性。,我看不出任何理由让 `printf` 成为你在日常活动中打印时的 _第一_ 选择,但是它是一个极好的工具来让你足够舒适,当你需要它时,将不会让你降低速度。
|
||||
|
||||
花一些时间学习你所选择语言中的 `printf` ,并且当你需要它时就使用它。它是一个强有力的你不会忘记的随时可用的工具。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/20/8/printf
|
||||
|
||||
作者:[Seth Kenlon][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://opensource.com/users/seth
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/coffee_tea_laptop_computer_work_desk.png?itok=D5yMx_Dr (Person drinking a hot drink at the computer)
|
||||
[2]: https://opensource.com/resources/python
|
||||
[3]: https://opensource.com/article/20/6/algol68
|
||||
[4]: http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html
|
||||
[5]: http://www.opengroup.org/onlinepubs/009695399/functions/atan.html
|
Loading…
Reference in New Issue
Block a user