099_formatting.zig 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //
  2. // The output on the console looks a bit rudimentary at first glance.
  3. // However, if you look at the development of modern computers, you can
  4. // see the enormous progress that has been made over the years.
  5. // Starting with monochrome lines on flickering CRT monitors, modern
  6. // terminal emulators offer a razor-sharp image with true color and
  7. // nearly infinite font size thanks to modern hardware.
  8. //
  9. // In addition, they have mastered ligatures and can represent almost
  10. // any character in any language. This also makes the output of programs
  11. // on the console more atractive than ever in recent years.
  12. //
  13. // This makes it all the more important to format the presentation of
  14. // results in an appealing way, because that is what users appreciate,
  15. // quick visual comprehension of the information.
  16. //
  17. // C has set standards here over the years, and Zig is preparing to
  18. // follow suit. Currently, however, it still lags a bit behind the model,
  19. // but the Zig community is working diligently behind the scenes on
  20. // further options.
  21. //
  22. // Nevertheless, it is time to take a closer look at the possibilities
  23. // that already exist. And of course we will continue this series loosely,
  24. // because Zig continues to grow almost daily.
  25. //
  26. // Since there is no proper documentation on the formatting yet, the most
  27. // important source here is the source code:
  28. //
  29. // https://github.com/ziglang/zig/blob/master/lib/std/fmt.zig#L29
  30. //
  31. //
  32. // And in fact, you already discover quite a lot of useful formatting.
  33. // These can be used in different ways, e.g. to convert numerical values
  34. // into text and for direct output to the console or to a file. The latter
  35. // is useful when large amounts of data are to be processed by other programs.
  36. //
  37. // However, we are concerned here exclusively with the output to the console.
  38. // But since the formatting instructions for files are the same, what you
  39. // learn applies universally.
  40. //
  41. // Since we basically write to debug output in Ziglings, our output usually
  42. // looks like this:
  43. //
  44. // std.debug.print("Text {placeholder} another text \n", .{variable});
  45. //
  46. // But how is the statement just shown formatted?
  47. //
  48. // This actually happens in several stages. On the one hand, escape
  49. // sequences are evaluated, there is the "\n" which means "line feed"
  50. // in the example. Whenever this statement is found, a new line is started
  51. // in the output. Escpape sequences can also be written one after the
  52. // other, e.g. "\n\n" will cause two line feeds.
  53. //
  54. // By the way, these formattings are passed directly to the terminal
  55. // program, i.e. escape sequences have nothing to do with Zig in this
  56. // respect. The formatting that Zig actually performs is found in the
  57. // curly bracket, the "placeholder", and affects the coresponding variable.
  58. //
  59. // And this is where it gets exciting, because numbers can have different
  60. // sizes, be positive or negative, with a decimal point or without,
  61. // and so on.
  62. //
  63. // In order to bring these then into a uniform format for the output,
  64. // instructions can be given to the placeholder:
  65. //
  66. // print("=> {x:0>4}", .{var});
  67. //
  68. // This instruction outputs a hexadecimal number with leading zeros.
  69. //
  70. // => 0x0017
  71. //
  72. // Let's move on to our exercise: we want to create a table that shows us
  73. // the multiplication of all numbers together from 1-15. So if you search
  74. // for the number '5' in the row and '4' in the column (or vice versa),
  75. // the result of '5 x 4 = 20' should be displayed there.
  76. //
  77. //
  78. const std = @import("std");
  79. const print = std.debug.print;
  80. pub fn main() !void {
  81. // the max. size of the table
  82. const size = 15;
  83. // print the header:
  84. //
  85. // we start with a single 'X' for the diagonal,
  86. // that means there is no result
  87. print("\n X |", .{});
  88. // header row with all numbers from 1 to size
  89. for (0..size) |n| {
  90. print("{d:>3} ", .{n + 1});
  91. }
  92. print("\n", .{});
  93. // row line
  94. var n: u8 = 0;
  95. while (n <= size) : (n += 1) {
  96. print("---+", .{});
  97. }
  98. print("\n", .{});
  99. // now the actual table
  100. for (0..size) |a| {
  101. print("{d:>2} |", .{a + 1});
  102. for (0..size) |b| {
  103. // what formatting is needed here?
  104. print("{???} ", .{(a + 1) * (b + 1)});
  105. }
  106. // after each row we use double line feed
  107. print("\n\n", .{});
  108. }
  109. }