{"id":22005,"date":"2024-08-31T18:44:48","date_gmt":"2024-08-31T18:44:48","guid":{"rendered":"https:\/\/wolles-elektronikkiste.de\/?p=22005"},"modified":"2024-09-02T19:39:19","modified_gmt":"2024-09-02T19:39:19","slug":"formatted-output","status":"publish","type":"post","link":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output","title":{"rendered":"Formatted output"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">About this Post<\/h2>\n\n<p>For formatted output on the serial monitor or on displays, you can use the convenient functions <code>sprintf()<\/code> and <code>snprintf()<\/code>. This allows you to combine different data types in a character array, display results in tabular form, select number systems and much more.<\/p>\r\n\r\n<p>This article is intended to provide an overview of the various possibilities of <code>sprintf()<\/code> or <code>snprintf()<\/code> and their siblings <code>sprintf_P()<\/code>, <code>snprintf_P()<\/code> and <code>printf()<\/code>. Some board packages do not support the formatting of decimal numbers using these functions. In these cases, you can take a detour via <code>dtostrf()<\/code>.<\/p>\r\n\r\n<p>The options for formatting output with <code>Serial.print()<\/code> and escape sequences are very limited. But to bring all formatting options together in one place, I will also go into this.<\/p>\n\n<p>What you can expect in this article:<\/p>\r\n<ul>\r\n<li><a href=\"#format_serial_print\">Formatted output with the Serial.print() options<\/a><\/li>\r\n<li><a href=\"#esc_seq\">escape sequences<\/a><\/li>\r\n<li><a href=\"#sprintf_and_co\">Formatted output with sprintf() Co<\/a><br>\r\n<ul>\r\n<li><a href=\"#func_overview\">Overview of the functions<\/a>\r\n<ul>\r\n<li><a href=\"#sprintf\">sprintf()<\/a><\/li>\r\n<li><a href=\"#snprintf\">snprintf()<\/a><\/li>\r\n<li><a href=\"#printf\">printf() \/ Serial.printf()<\/a><\/li>\r\n<li><a href=\"#snprintf_p\">Save SRAM with sprintf_P and snprintf_P()<\/a><\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><a href=\"#format_specifier\">Using format specifiers<\/a>\r\n<ul>\r\n<li><a href=\"#conv_specifier\">The conversion specifier<\/a><\/li>\r\n<li><a href=\"#sub_specifier\">The sub-specifiers<\/a><\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><a href=\"#example_sketches_sprintf\">Example sketches<\/a><\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><a href=\"#dtostrf\">Formatted output with dtostrf()<\/a>\r\n<ul>\r\n<li><a href=\"#example_sketch_dtostrf\">Example sketch dtostrf()<\/a><\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><a href=\"#example_sketch_table\">Example sketch for tabular output<\/a><\/li>\r\n<\/ul>\r\n\n<h2 class=\"wp-block-heading\" id=\"format_serial_print\">Formatted output with the Serial.print() options<\/h2>\n\n<p>If you pass a number to the function <code>Serial.print()<\/code> or <code>Serial.println()<\/code>, you can format it using a second parameter:<\/p>\r\n<p><code>Serial.print(val, format);<\/code><\/p>\r\n<p>For <code>format<\/code> you have the following options:&nbsp;<\/p>\r\n<ul>\r\n<li>You can define the number base <strong>for integers<\/strong>: <ul>\r\n<li><strong>HEX<\/strong>: Base 16, hexadecimal system<\/li>\r\n<li><strong>DEC<\/strong>: Base 10, decimal system (standard),<\/li>\r\n<li><strong>OCT<\/strong>: Base 8, octal system<\/li>\r\n<li><strong>BIN<\/strong>: Base 2, binary system<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><strong>For decimal numbers,<\/strong> you specify the number of decimal places (default: 2). The last digit is rounded. <\/li>\r\n<\/ul>\r\n<p>Here is a small example sketch:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"serial_print_format.ino\" data-enlighter-title=\"serial_print_format.ino\">void setup() {\r\n    Serial.begin(115200);\r\n    \/\/ delay(1000);  \/\/uncomment if your serial monitor is blank\r\n    int a = 193;\r\n    float f = PI; \/\/ PI = 3.1415926...\r\n    Serial.println(\"Output of 193 (dec.):\");\r\n    Serial.print(\"Hexadecimal: \"); Serial.println(a, HEX);\r\n    Serial.print(\"Decimal    : \"); Serial.println(a, DEC);\r\n    Serial.print(\"Octal      : \"); Serial.println(a, OCT);\r\n    Serial.print(\"Binary     : \"); Serial.println(a, BIN);\r\n    Serial.println(\"\\nOutput of Pi:\"); \/\/ here, I already used an escape sequence\r\n    Serial.print(\"1 decimal place : \"); Serial.println(f, 1);\r\n    Serial.print(\"2 decimal places: \"); Serial.println(f, 2);\r\n    Serial.print(\"3 decimal places: \"); Serial.println(f, 3);\r\n}\r\n\r\nvoid loop() {}<\/pre>\r\n\n<p>And here is the output:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_serial_print_format.png\"><img loading=\"lazy\" decoding=\"async\" width=\"573\" height=\"188\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_serial_print_format.png\" alt=\"Formatted output with Serial.print()\" class=\"wp-image-21854\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_serial_print_format.png 573w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_serial_print_format-300x98.png 300w\" sizes=\"auto, (max-width: 573px) 100vw, 573px\" \/><\/a><figcaption class=\"wp-element-caption\">Formatted output with Serial.print()<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Saving SRAM with the F-Macro<\/h4>\n\n<p>Constant text, i.e. everything in quotation marks in the above sketch, is an SRAM eater. With the F macro, you ensure that the character string to be output is not stored in the SRAM but in the flash: <\/p>\r\n<p><code>Serial.println(F(\"Output String\"));<\/code><\/p>\r\n<p>This has nothing to do with formatting, but it should be noted here for the sake of completeness because I will discuss a corresponding variant of the <code>sprintf()<\/code> function below. <\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"esc_seq\">Escape sequences<\/h2>\n\n<p>Escape sequences offer you further options for formatting the output of <code>Serial.print()<\/code> or outputting special characters. The use of escape sequences is not limited to <code>Serial.print()<\/code>, but can be used in all string objects or character arrays. <\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"escape_sequences.ino\" data-enlighter-title=\"escape_sequences.ino\">void setup() {\r\n    Serial.begin(115200);\r\n    \/\/ delay(1000);  \/\/uncomment if your serial monitor is blank\r\n    Serial.print(\"\\\\n outputs a line feed \\n\");\r\n    Serial.println(\"\\\\r outputs a carriage return \\r\"); \r\n    Serial.println(\"\\\\xXX outputs the ASCII character of 0xXX, e.g. \\\\x41:  \\x41\");\r\n    Serial.println(\"\\\\uXXXX outputs the unicode character of 0xXXXX, e.g. \\\\u21C4: \\u21C4\");\r\n    Serial.println(\"\\\\t outputs a tab, e.g.: 12\\t34 \");\r\n    Serial.println(\"\\\\\\\" outputs \\\"\");\r\n    Serial.println(\"\\\\\\' outputs \\'\");\r\n    Serial.println(\"\\\\\\\\ outputs \\\\\");\r\n    Serial.print(\"Serial.println() of \"); int numOfChars = Serial.println(\"12345\");\r\n    Serial.print(\"    ...prints \"); Serial.print(numOfChars); Serial.println(\" characters!\");\r\n}\r\n\r\nvoid loop() {}\r\n<\/pre>\r\n\n<p>The output is:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_escape_seq_eng.png\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_escape_seq_eng.png\" alt=\"Formatted output with escape sequences\" class=\"wp-image-21959\"\/><\/a><figcaption class=\"wp-element-caption\">Output of escape_sequences.ino<\/figcaption><\/figure>\n\n<p>In the last line, you can see that <code>Serial.println(\"...\")<\/code> generates two more characters than you might expect. This is due to the &#8220;hidden&#8221; carriage return and line feed. The function corresponds to <code>Serial.print(\"...\\r\\n\")<\/code>.  <\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"sprintf_and_co\">Formatted output with sprintf() Co<\/h2>\n\n<h3 class=\"wp-block-heading\" id=\"func_overview\">Overview of the functions<\/h3>\n\n<p>With the functions <code>sprintf()<\/code>, <code>snprintf()<\/code> <code>printf()<\/code> and <code>snprintf_P()<\/code> you have incomparably more powerful tools at your disposal.<\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"sprintf\">sprintf()<\/h4>\n\n<p><code>sprintf()<\/code> is defined as follows:<\/p>\r\n<p><code>int sprintf ( char *buf, const char *format, ... );<\/code><\/p>\r\n<p>Here, <code>format<\/code> contains the characters to be output and, if necessary, placeholders for variables with formatting instructions. These placeholders are also called format specifiers. They can be recognized by the preceding percent sign. The variables themselves are appended in the order in which their format specifiers appear, separated by commas:   <\/p>\r\n<p><code>sprintf(buf, \"... format_specifier_1 ... format_specifier_2 ... format_specifier_3....\", variable_1, variable_2, variable_3, ..,);<\/code><\/p>\r\n<p>The result is saved in the character array <code>buf<\/code> and can be output via <code>Serial.print()<\/code>.<\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"snprintf\">snprintf() vs. sprintf()<\/h4>\n\n<p>The function <code>sprintf()<\/code> writes the character string defined in <code>format<\/code> to <code>buf<\/code>, regardless of whether you have reserved enough memory for it or not. If <code>buf<\/code> is too small, you simply write beyond it &#8211; with unforeseeable consequences (see below).  &nbsp;<\/p>\r\n<p>The <code>snprintf()<\/code> function is safer. It differs from <code>sprintf()<\/code> by the concrete specification of the number of characters to be read in (here: &#8220;n&#8221;): <\/p>\r\n<p><code>int snprintf ( char *buf, size_t n, const char * format, ... );<\/code><\/p>\r\n<p>If you specify &#8220;n&#8221; with <code>sizeof(buf)<\/code>, you are on the safe side. At worst, part of what you wanted to spend will lost, but at least you won&#8217;t have any problems due to unwanted overwriting of memory. <\/p>\r\n<p>Even though I recommend <code>snsprintf()<\/code>, I will use <code>sprintf()<\/code> in the rest of the article to focus on the formatting options. <\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"printf\">printf() \/ Serial.printf()<\/h4>\n\n<p>You may be wondering whether you can save yourself the detour via the character array <code>buf<\/code>. In fact, you can use the <code>Serial.printf()<\/code> function on some microcontroller boards (e.g. ESP32), but not, for example, on the classic AVR-based Arduinos. <\/p>\r\n<p><code>int Serial.printf(const char * format, ....);<\/code><\/p>\r\n<p>If the board of your choice supports <code>printf()<\/code>, then you can simply transfer everything from <code>sprintf()<\/code>. However, you should consider whether you really want to write your sketches board-specifically. <\/p>\r\n<p>The <code>printf()<\/code> function (i. e. not: <code>Serial.printf()<\/code>) is generally available:<\/p>\r\n<p><code>int printf (const char * format, ... );<\/code><\/p>\r\n<p>However, you cannot simply generate an output on the serial monitor because its input and output is not defined. If you are interested in details and a workaround, look <a href=\"https:\/\/playground.arduino.cc\/Main\/Printf\/\" target=\"_blank\" rel=\"noopener\">here<\/a> and <a href=\"https:\/\/forum.arduino.cc\/t\/ot-wolle-erklart-formatierte-ausgabe\/1297213\/5\" target=\"_blank\" rel=\"noopener\">here<\/a>. <\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"snprintf_p\">Saving SRAM with sprintf_P() and snprintf_P()<\/h4>\n\n<p>With the variants <code>sprintf_P()<\/code> and <code>snprintf_P()<\/code> you can achieve that <code>format<\/code> is not read from the SRAM, but from flash:<\/p>\r\n<p><code>int sprintf_P ( char *buf, const char* PSTR(format), ... );<\/code><\/p>\r\n<p><code>int snprintf_P ( char *buf, size_t n, const char* PSTR(format), ... );<\/code><\/p>\r\n<p>The PSTR macro is similar to the F macro. However, the latter is incompatible with <code>sprintf_P()<\/code> and <code>snprintf_P()<\/code>. If you want to know exactly: The F macro returns <code>__FlashStringHelper*<\/code>, but <code>sprintf_P()<\/code> and <code>snprintf_P()<\/code> expect <code>const char*<\/code> as a parameter. And this is exactly what the PSTR macro generates.   <\/p>\r\n\n<h3 class=\"wp-block-heading\" id=\"format_specifier\">Using format specifiers<\/h3>\n\n<p>A format specifier consists of the percent sign, some optional sub-specifiers and the conversion specifier:<\/p>\r\n\n<p>% [flags] [width] [.precision] [length] conversion specifier<\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"conv_specifier\">The conversion specifier<\/h4>\n\n<p>You use the conversion specifier to define what you want to output the placeholders as. The conversion specifier must, of course, be compatible with the variable to be output. Here are the options:  <\/p>\r\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/conv_format_specifier__eng.png\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/conv_format_specifier__eng.png\" alt=\"Options for the conversion specifier for the formatted output &#10;\" class=\"wp-image-21967\"\/><\/a><figcaption class=\"wp-element-caption\">Options for the conversion specifier<\/figcaption><\/figure>\n\n<p>Not all conversion specifiers are supported by all board packages. Users of AVR-based boards, e.g. Arduino UNO R3, classic Arduino Nano etc., will miss the options for decimal numbers (decimal numbers = fixed-point and floating-point numbers) the most. There is a detour via <code>dtostrf()<\/code>, which we will come to below. <\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"sub_specifier\">The sub-specifiers<\/h4>\n\n<p>You have the following options for the <strong>flag<\/strong>:<\/p>\r\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/sprintf_flags_engl.png\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/sprintf_flags_engl.png\" alt=\"Formatted output - flags for the format specifier\" class=\"wp-image-21838\" style=\"width:636px;height:auto\"\/><\/a><figcaption class=\"wp-element-caption\">Flags for the format specifier<\/figcaption><\/figure>\n\n<p>The <strong>width<\/strong> is the minimum width for the character string defined in the format specifier. If the character string is longer than defined in &#8220;width&#8221; or the same length, then &#8220;width&#8221; has no effect. If the character string is shorter than width, the difference is filled with spaces or zeros (see flags).  <\/p>\r\n\n<p>The effect of <strong>precision<\/strong> depends on the conversion specifier:<\/p>\r\n<ul>\r\n<li><strong>f, e, E, a, A<\/strong>: the precision specifies the number of decimal places.<\/li>\r\n<li><strong>g, G<\/strong>: the precision specifies the total number of digits before <em>and<\/em> after the decimal point.<\/li>\r\n<li><strong>d, i, o, u, x, X<\/strong>: the precision specifies the minimum width. Any spaces are filled with leading zeros. <\/li>\r\n<li><strong>s<\/strong>: the precision specifies the maximum number of characters to be output. Characters exceeding this are truncated. <\/li>\r\n<\/ul>\r\n\n<p>The effect of the <strong>length<\/strong> also depends on the conversion specifier:<\/p>\r\n<ul>\r\n<li><strong>l (small &#8220;L&#8221;): <\/strong>turns d, i, o, u, x, X into a &#8220;long int&#8221; or an &#8220;unsigned long int&#8221;.<\/li>\r\n<li><strong>ll (small &#8220;Ls&#8221;)<\/strong>: turns d, i, o, u, x, X into a &#8220;long long int&#8221; or an &#8220;unsigned long long int&#8221;.<\/li>\r\n<li><strong>L<\/strong>: turns f into a long double.<\/li>\r\n<\/ul>\r\n\n<h3 class=\"wp-block-heading\" id=\"example_sketches_sprintf\">Example sketches<\/h3>\n\n<h4 class=\"wp-block-heading\">Basic example<\/h4>\n\n<p>The following sketch illustrates how to use the format specifiers in <code>sprintf()<\/code>, <code>snprintf()<\/code> and <code>snprintf_P()<\/code>. I will initially dispense with sub-specifiers: <\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sprintf_snprintf_snprintf_P_basic.ino\" data-enlighter-title=\"sprintf_snprintf_snprintf_P_basic.ino\">void setup() {\r\n    Serial.begin(115200);\r\n    char buf[60]; \/\/ more than enough capacity\r\n    int a = 42;\r\n    char str[] = \"universe\";\r\n    sprintf(buf, \"%d is the meaning of life, %s %s\", a, str, \"and everything\");\r\n    Serial.println(buf);\r\n    snprintf(buf, 26, \"%d is the meaning of life, %s %s\", a, str, \"and everything\");\r\n    Serial.println(buf);\r\n    snprintf(buf, sizeof(buf), \"%d is the meaning of life, %s %s\", a, str, \"and everything\");\r\n    Serial.println(buf);\r\n    snprintf_P(buf, sizeof(buf), PSTR(\"%d is the meaning of life, %s %s\"), a, str, \"and everything\");\r\n    Serial.println(buf);\r\n}\r\n\r\nvoid loop() {}<\/pre>\r\n\n<p>Here is the output:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_spintf_basics.png\"><img loading=\"lazy\" decoding=\"async\" width=\"592\" height=\"80\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_spintf_basics.png\" alt=\"\" class=\"wp-image-21883\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_spintf_basics.png 592w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_spintf_basics-300x41.png 300w\" sizes=\"auto, (max-width: 592px) 100vw, 592px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of sprintf_snprintf_snprintf_P_basic.ino<\/figcaption><\/figure>\n\n<h5 class=\"wp-block-heading\">Calculation of buf<\/h5>\n\n<p>When calculating the size of the &#8220;target string&#8221; (<code>buf<\/code>), it should be noted that the number of characters to be output is taken as the basis and not the size of the variable. Example: An integer uses 2 bytes on an AVR-based Arduino. However, how much memory the integer value requires in <code>buf<\/code> depends on the number of digits and possibly on the formatting parameters (additional signs, spaces, &#8220;0x&#8221; etc.).  <\/p>\r\n<p>Don&#8217;t forget to reserve one character for the null terminator.<\/p>\r\n<p>Here you can see what can happen if you define a size for <code>buf<\/code> that is too small:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"wrong_buf_size.ino\" data-enlighter-title=\"wrong_buf_size.ino\">void setup() {\r\n    Serial.begin(115200);\r\n    char buf[5]; \r\n    char buf2[6];\r\n    char str[] = \"1234567890\";\r\n    sprintf(buf, \"%s\", str);\r\n    Serial.print(\"buf : \");\r\n    Serial.println(buf);\r\n    sprintf(buf2, \"%s\", str);\r\n    Serial.print(\"buf2: \");\r\n    Serial.println(buf2);\r\n    Serial.print(\"buf : \");\r\n    Serial.println(buf);  \r\n}\r\n\r\nvoid loop() {}<\/pre>\r\n\n<p>The output, tested on an Arduino Nano, is:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_wrong_buf_size.png\"><img loading=\"lazy\" decoding=\"async\" width=\"259\" height=\"57\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_wrong_buf_size.png\" alt=\"\" class=\"wp-image-21946\"\/><\/a><figcaption class=\"wp-element-caption\">Output of wrong_buf_size.ino on an Arduino Nano<\/figcaption><\/figure>\n\n<p>As you can see, the error only becomes apparent after the string has been written to <code>buf2<\/code> and its remainder, which does not fit into the reserved memory, &#8220;protrudes&#8221; into the memory reserved for <code>buf<\/code>.&nbsp;<\/p>\r\n\n<p>On an ESP32, the SRAM is organized differently. Here, <code>buf<\/code> is overwritten &#8220;coming from the other side&#8221;: <\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_wrong_buf_size_esp32-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"353\" height=\"55\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_wrong_buf_size_esp32-1.png\" alt=\"\" class=\"wp-image-22007\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_wrong_buf_size_esp32-1.png 353w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_wrong_buf_size_esp32-1-300x47.png 300w\" sizes=\"auto, (max-width: 353px) 100vw, 353px\" \/><\/a><figcaption class=\"wp-element-caption\">Output of wrong_buf_size.ino on an ESP32<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Example: formatted output of integers<\/h4>\n\n<p>The next example sketch plays with some sub-specifiers for integers.<\/p>\r\n\n<div class=\"scroll-paragraph\">\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sprintf_integers.ino\" data-enlighter-title=\"sprintf_integers.ino\">void setup() {\r\n    Serial.begin(115200);\r\n    char buf[50];\r\n    int a = 193;\r\n    sprintf(buf, \"Default integer (signed)       : %i\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Defined width, right-justify   : %5d%5d\", a, a+a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Defined width, left-justify    : %-5d%-5d\", a, a+a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Defined width, preceeding zeros: %05d\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"With sign                      : %+d\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Hexadecimal, lowercase         : %x \", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Hexadecimal, uppercase         : %X\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Hexadecimal, with \\\"0X\\\"         : %#X\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Octal                          : %o\", a);\r\n    Serial.println(buf);\r\n    Serial.print(\"No binary option for sprintf   : \"); Serial.println(a, BIN);\r\n    sprintf(buf, \"Long integer                   : %ld\", 1234567890);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"%-31s%s%05d\", \"Alternative output\", \": \", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Address of buf                 : %p\", buf);\r\n    Serial.println(buf);\r\n}\r\n\r\nvoid loop() {}<\/pre>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n\n<p>Because I wanted to focus on the essentials, I have not used the full range of formatting options, for example to align the colons. However, to show how this can be done, I have made an exception for the formatting of the penultimate output line (&#8220;Alternative output&#8221;). &nbsp;<\/p>\r\n<p>Here is the output:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_sprintf_integers_engl.png\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_sprintf_integers_engl.png\" alt=\"\" class=\"wp-image-21836\"\/><\/a><figcaption class=\"wp-element-caption\">Ausgabe von sprintf_integers.ino<\/figcaption><\/figure>\n\n<h4 class=\"wp-block-heading\">Example: formatted output of decimal numbers<\/h4>\n\n<p>As already mentioned, formatting of decimal numbers using <code>sprintf()<\/code> does not work on the AVR-based microcontroller boards. I have tried the following sketch on an ESP32 board: <\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"sprintf_floating_point.ino\" data-enlighter-title=\"sprintf_floating_point.ino\">void setup() {\r\n    Serial.begin(115200);\r\n    char buf[60];\r\n    double a = PI; \/\/ PI = 3.1415926...\r\n    sprintf(buf, \"Default double                : %f\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Specified length and precision: %6.2f\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Scientific notation, lowercase: %e\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \" \\\" , with length and precision: %10.3e\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Scientific notation, uppercase: %E\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Shortest, lowercase           : %g\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Shortest, lowercase           : %g\", 1000000 * a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Shortest, uppercase           : %G\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Shortest, uppercase           : %G\", 1000000 * a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Hex floating point, lowercase : %a\", a);\r\n    Serial.println(buf);\r\n    sprintf(buf, \"Hex floating point, uppercase : %A\", a);\r\n    Serial.println(buf);\r\n}\r\n\r\nvoid loop() {}\r\n<\/pre>\r\n\n<p>The output is:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_sprintf_floats_eng-1.png\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_sprintf_floats_eng-1.png\" alt=\"\" class=\"wp-image-21943\"\/><\/a><figcaption class=\"wp-element-caption\">Output of sprintf_floats.ino<\/figcaption><\/figure>\n\n<p>You could also define Pi as a float data type in the example. You can then see the difference after the seventh digit. <\/p>\r\n\n<h2 class=\"wp-block-heading\" id=\"dtostrf\">Formatted output with dtostrf()<\/h2>\n\n<p>If formatting decimal numbers using <code>sprintf()<\/code> or <code>%f<\/code> does not work, you can use the <code>dtostrf()<\/code> function:<\/p>\r\n<p><code>dtostrf(double f, int [-]width, int precision, char *buf)<\/code><\/p>\r\n<p>The parameters are:<\/p>\r\n<ul>\r\n<li><strong>f<\/strong>: the number to be converted into a character array.<\/li>\r\n<li><strong>width<\/strong>: the minimum width. <ul>\r\n<li>an optional &#8220;-&#8221; forces the sign to be output.<\/li>\r\n<\/ul>\r\n<\/li>\r\n<li><strong>precision<\/strong>: the decimal places.<\/li>\r\n<li><strong>buf<\/strong>: the output string.<\/li>\r\n<\/ul>\r\n<p>When calculating the size of the &#8220;target string&#8221; (<code>buf<\/code>), you must take care that the number of characters to be output (including spaces) and the null terminator must fit.<\/p>\r\n<p>For the output, it makes sense to combine the output of <code>dtostrf()<\/code> with <code>sprintf()<\/code>.<\/p>\r\n\n<h4 class=\"wp-block-heading\" id=\"example_sketch_dtostrf\">Example sketch dtostrf()<\/h4>\n\n<p>Here are some examples of the use of <code>dtostrf()<\/code>:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"dtostrf.ino\" data-enlighter-title=\"dtostrf.ino\">void setup() {\r\n    Serial.begin(115200);\r\n    char buf_1[10];\r\n    char buf_2[40]; \/\/ \r\n    int i = 193;\r\n    double a = PI; \/\/ PI = 3.1415926...\r\n    \r\n    dtostrf(a, 1, 2, buf_1);\r\n    sprintf(buf_2, \"Width > minimum width : %s\", buf_1);\r\n    Serial.println(buf_2);\r\n    \r\n    dtostrf(a, 7, 2, buf_1);\r\n    sprintf(buf_2, \"Right-justified:      : %s\", buf_1);\r\n    Serial.println(buf_2);\r\n\r\n    dtostrf(a, -7, 2, buf_1);\r\n    sprintf(buf_2, \"Left-justified        : %s\", buf_1);\r\n    Serial.println(buf_2);\r\n\r\n    dtostrf(i, 1, 0, buf_1);\r\n    sprintf(buf_2, \"Integer               : %s\", buf_1);\r\n    Serial.println(buf_2);\r\n\r\n    dtostrf(i, 7, 2, buf_1);\r\n    sprintf(buf_2, \"\\\"Integer to double\\\"   : %s\", buf_1);\r\n    Serial.println(buf_2);   \r\n}\r\n\r\nvoid loop() {}<\/pre>\r\n\n<p>The output of the sketch is:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_dtostr_eng.png\"><img decoding=\"async\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_dtostr_eng.png\" alt=\"\" class=\"wp-image-21941\"\/><\/a><figcaption class=\"wp-element-caption\">Output of dtostrf.ino<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"example_sketch_table\">Example sketch for tabular output<\/h2>\n\n<p>Finally, here is an example of what a clear output of data records could look like:<\/p>\r\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-group=\"formatted_table.ino\" data-enlighter-title=\"formatted_table.ino\">struct dataset {\r\n    char name[10];\r\n    unsigned int age;\r\n    unsigned int size;\r\n    float weight;\r\n};\r\n\r\nvoid setup() {\r\n    dataset mia {\"Mia\", 1, 75, 9.3};\r\n    dataset michael {\"Michael\", 60, 185, 103.7};\r\n    dataset kevin {\"Kevin\", 18, 183, 75.2};\r\n\r\n    Serial.begin(115200);\r\n    print_data(&amp;mia);\r\n    print_data(&amp;michael);\r\n    print_data(&amp;kevin);\r\n}\r\n\r\nvoid print_data(dataset *set){\r\n    char buf[40];\r\n    char weightBuf[7]; \/\/ width 6 + null-terminator\r\n    dtostrf(set-&gt;weight, 6, 1, weightBuf); \r\n    sprintf(buf, \"| %-8s|%4d |%4d |%s |\", set-&gt;name, set-&gt;age, set-&gt;size, weightBuf);\r\n    Serial.println(buf);\r\n    Serial.flush();\r\n}\r\n\r\nvoid loop() {}<\/pre>\r\n\n<p>As the data records are passed to <code>print_data<\/code> as pointers, the arrow operator must be used instead of the dot operator. Otherwise, the sketch should be self-explanatory.<\/p>\r\n<p>Here is the output:<\/p>\r\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"395\" height=\"60\" src=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_formatted_table.png\" alt=\"\" class=\"wp-image-21950\" srcset=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_formatted_table.png 395w, https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/output_formatted_table-300x46.png 300w\" sizes=\"auto, (max-width: 395px) 100vw, 395px\" \/><figcaption class=\"wp-element-caption\">Output of formatted_table.ino<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Generating formatted output with sprintf(), snprintf() and dtostrf() is convenient and simple. I will explain the various options as well as the pitfalls. <\/p>\n","protected":false},"author":1,"featured_media":21956,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[567,575],"tags":[1466,2387,2566,2565,2564,2568,1044,2572,1553,2571,2388,2561,2569,2570,2563,2562,2361,2567],"class_list":["post-22005","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-other-stuff","category-software-and-tools","tag-accuracy","tag-binary","tag-character-array-en","tag-double-en","tag-dtostrf-en","tag-escape-sequences","tag-esp32-en","tag-flag-en","tag-float-en","tag-floating-point-numbers","tag-hexadecimal","tag-precision","tag-saving-sram","tag-snprintf_p-en","tag-snprintf-en","tag-sprintf-en","tag-string-en","tag-width"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Formatted output &#8226; Wolles Elektronikkiste<\/title>\n<meta name=\"description\" content=\"Generating formatted output with the sprintf(), snprintf() and dtostrf() functions is easy. However, there are some pitfalls.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Formatted output &#8226; Wolles Elektronikkiste\" \/>\n<meta property=\"og:description\" content=\"Generating formatted output with the sprintf(), snprintf() and dtostrf() functions is easy. However, there are some pitfalls.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output\" \/>\n<meta property=\"og:site_name\" content=\"Wolles Elektronikkiste\" \/>\n<meta property=\"article:published_time\" content=\"2024-08-31T18:44:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-09-02T19:39:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/post_image__formatted_output.png\" \/>\n\t<meta property=\"og:image:width\" content=\"920\" \/>\n\t<meta property=\"og:image:height\" content=\"834\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Wolfgang Ewald\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Wolfgang Ewald\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output\"},\"author\":{\"name\":\"Wolfgang Ewald\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"headline\":\"Formatted output\",\"datePublished\":\"2024-08-31T18:44:48+00:00\",\"dateModified\":\"2024-09-02T19:39:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output\"},\"wordCount\":1617,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/post_image__formatted_output.png\",\"keywords\":[\"accuracy\",\"binary\",\"character array\",\"double\",\"dtostrf()\",\"escape sequences\",\"ESP32\",\"flag\",\"float\",\"floating point numbers\",\"hexadecimal\",\"precision\",\"saving SRAM\",\"snprintf_P()\",\"snprintf()\",\"sprintf()\",\"String\",\"Width\"],\"articleSection\":[\"Other stuff\",\"Software and tools\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output\",\"name\":\"Formatted output &#8226; Wolles Elektronikkiste\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/post_image__formatted_output.png\",\"datePublished\":\"2024-08-31T18:44:48+00:00\",\"dateModified\":\"2024-09-02T19:39:19+00:00\",\"description\":\"Generating formatted output with the sprintf(), snprintf() and dtostrf() functions is easy. However, there are some pitfalls.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#primaryimage\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/post_image__formatted_output.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2024\\\/08\\\/post_image__formatted_output.png\",\"width\":920,\"height\":834},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\\\/formatted-output#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Formatted output\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#website\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en\",\"name\":\"Wolles Elektronikkiste\",\"description\":\"Die wunderbare Welt der Elektronik\",\"publisher\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/en#\\\/schema\\\/person\\\/b774e4d64b4766889a2f7c6e5ec85b46\",\"name\":\"Wolfgang Ewald\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"url\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"contentUrl\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\",\"width\":512,\"height\":512,\"caption\":\"Wolfgang Ewald\"},\"logo\":{\"@id\":\"https:\\\/\\\/wolles-elektronikkiste.de\\\/wp-content\\\/uploads\\\/2019\\\/03\\\/cropped-Logo-1.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Formatted output &#8226; Wolles Elektronikkiste","description":"Generating formatted output with the sprintf(), snprintf() and dtostrf() functions is easy. However, there are some pitfalls.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output","og_locale":"en_US","og_type":"article","og_title":"Formatted output &#8226; Wolles Elektronikkiste","og_description":"Generating formatted output with the sprintf(), snprintf() and dtostrf() functions is easy. However, there are some pitfalls.","og_url":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output","og_site_name":"Wolles Elektronikkiste","article_published_time":"2024-08-31T18:44:48+00:00","article_modified_time":"2024-09-02T19:39:19+00:00","og_image":[{"width":920,"height":834,"url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/post_image__formatted_output.png","type":"image\/png"}],"author":"Wolfgang Ewald","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Wolfgang Ewald","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#article","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output"},"author":{"name":"Wolfgang Ewald","@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"headline":"Formatted output","datePublished":"2024-08-31T18:44:48+00:00","dateModified":"2024-09-02T19:39:19+00:00","mainEntityOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output"},"wordCount":1617,"commentCount":0,"publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/post_image__formatted_output.png","keywords":["accuracy","binary","character array","double","dtostrf()","escape sequences","ESP32","flag","float","floating point numbers","hexadecimal","precision","saving SRAM","snprintf_P()","snprintf()","sprintf()","String","Width"],"articleSection":["Other stuff","Software and tools"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output","url":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output","name":"Formatted output &#8226; Wolles Elektronikkiste","isPartOf":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#website"},"primaryImageOfPage":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#primaryimage"},"image":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#primaryimage"},"thumbnailUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/post_image__formatted_output.png","datePublished":"2024-08-31T18:44:48+00:00","dateModified":"2024-09-02T19:39:19+00:00","description":"Generating formatted output with the sprintf(), snprintf() and dtostrf() functions is easy. However, there are some pitfalls.","breadcrumb":{"@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wolles-elektronikkiste.de\/en\/formatted-output"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#primaryimage","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/post_image__formatted_output.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2024\/08\/post_image__formatted_output.png","width":920,"height":834},{"@type":"BreadcrumbList","@id":"https:\/\/wolles-elektronikkiste.de\/en\/formatted-output#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/wolles-elektronikkiste.de\/en"},{"@type":"ListItem","position":2,"name":"Formatted output"}]},{"@type":"WebSite","@id":"https:\/\/wolles-elektronikkiste.de\/en#website","url":"https:\/\/wolles-elektronikkiste.de\/en","name":"Wolles Elektronikkiste","description":"Die wunderbare Welt der Elektronik","publisher":{"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wolles-elektronikkiste.de\/en?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/wolles-elektronikkiste.de\/en#\/schema\/person\/b774e4d64b4766889a2f7c6e5ec85b46","name":"Wolfgang Ewald","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","url":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","contentUrl":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png","width":512,"height":512,"caption":"Wolfgang Ewald"},"logo":{"@id":"https:\/\/wolles-elektronikkiste.de\/wp-content\/uploads\/2019\/03\/cropped-Logo-1.png"}}]}},"_links":{"self":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/22005","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/comments?post=22005"}],"version-history":[{"count":0,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/posts\/22005\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media\/21956"}],"wp:attachment":[{"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/media?parent=22005"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/categories?post=22005"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wolles-elektronikkiste.de\/en\/wp-json\/wp\/v2\/tags?post=22005"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}