Difference between revisions of "printf"

From SEGGER Wiki
Jump to: navigation, search
m
 
(7 intermediate revisions by one other user not shown)
Line 24: Line 24:
   
 
== Parameter specification==
 
== Parameter specification==
=== Type specification ===
 
 
===Type field===
 
===Type field===
 
The Type field can be any of:
 
The Type field can be any of:
Line 36: Line 35:
 
|-
 
|-
 
| <code>d</code>, <code>i</code>
 
| <code>d</code>, <code>i</code>
|<code>int</code> as a signed [[decimal]] number. <code>%d</code> and <code>%i</code> are synonymous for output, but are different when used with <code>[[scanf]]()</code> for input (where using <code>%i</code> will interpret a number as hexadecimal if it's preceded by <code>0x</code>, and octal if it's preceded by <code>0</code>.)
+
|<code>int</code> as a signed [[decimal]] number. <code>%d</code> and <code>%i</code> produce identical output.)
 
|-
 
|-
 
| <code>u</code>
 
| <code>u</code>
Line 42: Line 41:
 
|-
 
|-
 
| <code>f</code>, <code>F</code>
 
| <code>f</code>, <code>F</code>
  +
|<code>double</code> in normal (fixed-point) notation.
|<code>double</code> in normal ([[Fixed-point arithmetic|fixed-point]]) notation. <code>f</code> and <code>F</code> only differs in how the strings for an infinite number or NaN are printed (<code>inf</code>, <code>infinity</code> and <code>nan</code> for <code>f</code>; <code>INF</code>, <code>INFINITY</code> and <code>NAN</code> for <code>F</code>).
 
|-
 
| <code>e</code>, <code>E</code>
 
|<code>double</code> value in standard form ([<code>-</code>]d.ddd <code>e</code>[<code>+</code>/<code>-</code>]ddd). An <code>E</code> conversion uses the letter <code>E</code> (rather than <code>e</code>) to introduce the exponent. The exponent always contains at least two digits; if the value is zero, the exponent is <code>00</code>. In Windows, the exponent contains three digits by default, e.g. <code>1.5e002</code>, but this can be altered by Microsoft-specific <code>_set_output_format</code> function.
 
|-
 
| <code>g</code>, <code>G</code>
 
|<code>double</code> in either normal or exponential notation, whichever is more appropriate for its magnitude. <code>g</code> uses lower-case letters, <code>G</code> uses upper-case letters. This type differs slightly from fixed-point notation in that insignificant zeroes to the right of the decimal point are not included. Also, the decimal point is not included on whole numbers.
 
 
|-
 
|-
 
| <code>x</code>, <code>X</code>
 
| <code>x</code>, <code>X</code>
 
|<code>unsigned int</code> as a [[hexadecimal]] number. <code>x</code> uses lower-case letters and <code>X</code> uses upper-case.
 
|<code>unsigned int</code> as a [[hexadecimal]] number. <code>x</code> uses lower-case letters and <code>X</code> uses upper-case.
|-
 
| <code>o</code>
 
|<code>unsigned int</code> in octal.
 
 
|-
 
|-
 
| <code>s</code>
 
| <code>s</code>
Line 61: Line 51:
 
| <code>c</code>
 
| <code>c</code>
 
|<code>char</code> (character).
 
|<code>char</code> (character).
|-
 
| <code>p</code>
 
|<code>void *</code> (pointer to void) in an implementation-defined format.
 
|-
 
| <code>a</code>, <code>A</code>
 
|<code>double</code> in hexadecimal notation, starting with <code>0x</code> or <code>0X</code>. <code>a</code> uses lower-case letters, <code>A</code> uses upper-case letters.<ref>{{cite web|url=https://www.gnu.org/software/libc/manual/html_node/Table-of-Output-Conversions.html#Table-of-Output-Conversions |title="The GNU C Library Reference Manual", "12.12.3 Table of Output Conversions" |publisher=Gnu.org |date= |accessdate=2014-03-17}}</ref><ref>
 
[http://www.cplusplus.com/reference/cstdio/printf/ "printf"]
 
(<code>%a</code> added in C99)
 
</ref> (C++11 iostreams have a <code>hexfloat</code> that works the same).
 
|-
 
| <code>n</code>
 
| Print nothing, but writes the number of characters successfully written so far into an integer pointer parameter.<br>Java: indicates a platform neutral newline/carriage return.<ref>{{cite web|url=https://docs.oracle.com/javase/tutorial/java/data/numberformat.html|title=Formatting Numeric Print Output |author=|date=|website=The Java Tutorials | publisher=Oracle Inc.|accessdate=19 March 2018}}</ref><br> Note: This can be utilized in [[Uncontrolled format string]] exploits.
 
 
|}
 
|}
  +
== Formatting ==
  +
Formatting means replacing the parameter placeholders, such as %d or %s, by the actual values.
  +
In most systems, this is done by the target. In larger systems, this is fine, but it comes at a price:
  +
The formatting function needs to do the parsing and needs to know all parameter types. This results in a lot of code, basically used for terminal out, so for debugging purposes. The amount of code varies, depending on which functionality is actually supported by the formatter, but is in general between about 3 KiB and up to 20 KiB.
  +
In many IDEs, the capabilities of the formatter can be selected, in order to choose a formatter with just the required capabilities with minimum size.
  +
Some IDEs such as Rowley's Crossworks and SEGGER's Embedded Studio also come with the ability to do
  +
[[Host-based_formatting |host-side formatting]]. With Host-side or host-based formatting, the host reads the parameters and performs the formatting on the host, which eliminates the requirement to have the formatting code on the target. This is a huge advantage for smaller targets, especially Microcontrollers with limited amount of Program memory (Flash memory).

Latest revision as of 09:09, 27 May 2021

"printf" is a function in the C-standard library that outputs text to standard output. Standard output is typically the terminal or debug console, depending on the system the program is running on. The f stands for formatted, allowing the function to output not just fixed strings, but also text with variable data in it.

Hello world

The simplest of all C-programs is known as "Hello world" program. It outputs "Hello world", using printf.

#include <stdio.h>

int main(void) {
  printf("Hello world!\n");
  return 0;
}

Using parameters

Parameters need to be specified in the format string. A parameter definition starts with a % character. A simple example with one numerical parameter looks as below:

  printf("Total sum is: %d\n", Sum);

Parameter specification

Type field

The Type field can be any of:

Character Description
% Prints a literal % character (this type doesn't accept any flags, width, precision, length fields).
d, i int as a signed decimal number. %d and %i produce identical output.)
u Print decimal unsigned int.
f, F double in normal (fixed-point) notation.
x, X unsigned int as a hexadecimal number. x uses lower-case letters and X uses upper-case.
s null-terminated string.
c char (character).

Formatting

Formatting means replacing the parameter placeholders, such as %d or %s, by the actual values. In most systems, this is done by the target. In larger systems, this is fine, but it comes at a price: The formatting function needs to do the parsing and needs to know all parameter types. This results in a lot of code, basically used for terminal out, so for debugging purposes. The amount of code varies, depending on which functionality is actually supported by the formatter, but is in general between about 3 KiB and up to 20 KiB. In many IDEs, the capabilities of the formatter can be selected, in order to choose a formatter with just the required capabilities with minimum size. Some IDEs such as Rowley's Crossworks and SEGGER's Embedded Studio also come with the ability to do host-side formatting. With Host-side or host-based formatting, the host reads the parameters and performs the formatting on the host, which eliminates the requirement to have the formatting code on the target. This is a huge advantage for smaller targets, especially Microcontrollers with limited amount of Program memory (Flash memory).