Output Syntax

To output formatted strings use the routines DiagnosticOutput, WarningOutput, CriticalOutput, DebugOutput, OutputWithFlags, FormatString and FormatCString.

They use the following syntax:

"@" is the placeholder for any parameter. Formatting details are optional and can follow using curly brackets. "@@" is the placeholder for the actual @ character. To use a format string that has two placeholders directly behind one another use "@{}@"

As a parameter you can use any datatype that has ToString() defined. By default this is any integral data type, String, CString, Url, Data, Container, Id, BaseArray, BlockArray, PointerArray, SortedArray, HashMap, TimeValue etc.

Call Output

Comment

@

If there is only one parameter no formatting takes place!

Int i = 5; DiagnosticOutput("@@@", i);
@5

The first @ results in the actual character.

Int i = 5, j = 2; DiagnosticOutput("@{}@", i, j);
52

{} inbetween defines two parameters directly after another instead of the @ character.



Formatting Integer values

  • "@{number}" formats the integer so that the resulting string has 'number' characters. If the number is too short fill characters (by default spaces) will be added in front of it. If the number does not fit however it is still printed in full length.
  • "@{'fillcharacter'}" specifies the fill character that is used instead of spaces. This option only makes sense in combination with a number
  • "@{x}" outputs the number as a hex value. The characters 'a'..'f' will be printed in lowercase letters. The output length depends on the input value, so if the input is 8-bit the result will be 2 characters long; if the input is 16-bit 4 characters etc.
  • "@{X}" like before, but prints the characters 'A'..'F' in uppercase letters.
  • "@{y}" outputs the number as a hex value. The characters 'a'..'f' will be printed in lowercase letters. No leading zeros will be printed.
  • "@{Y}" like before, but prints the characters 'A'..'F' in uppercase letters.
  • "@{c}" outputs the actual character instead of the number. Cannot be combined with any of the other options.
  • "@{m}" outputs a memory size in mibibytes (GiB, MiB, KiB, bytes). For example a value of 1343443 is output as 1.28 MiB. Cannot be combined with hexadecimal or character output.
  • "@{M}" outputs a memory size in megabytes (GB, MB, KB, bytes). For example a value of 1343443 is output as 1.34 MB. Cannot be combined with hexadecimal or character output.
Call Output

Comment

Int i = 97; DiagnosticOutput("@", i);
97

Regular number output.

Char i = 97; DiagnosticOutput("@", i);
97

Independent of the input width the actual number value is printed.

Int i = 97; DiagnosticOutput("@{c}", i);
a

'c' is the formatting statement for character.

Int i = -97; DiagnosticOutput("@{5}", i);
__-97

Five characters are printed. To visualize this a '_' is shown instead of a whitespace.

Int i = -9700; DiagnosticOutput("@{2}", i);
-9700

If not enough characters are provided the full number is still printed.

Int i = -97; DiagnosticOutput("@{5'E'}", i);
EE-97

A fill character has been provided.

UInt32 i = 95; DiagnosticOutput("@{x}", i);
0000005f

Note that 'Int' results in 16 characters for a 64-bit compile and 8 characters for a 32-bit compile.
Use UInt32 or UInt64 for a defined length.

UInt32 i = 95; DiagnosticOutput("@{X}", i);
0000005F

Like the example before, but with uppercase letters.

UInt32 i = 15; DiagnosticOutput("@{y}", i);
f

Like before, but no leading zeros are printed.

UInt32 i = 15; DiagnosticOutput("@{Y}", i);
F

Like before, but with uppercase letters.

UInt16 i = 189; DiagnosticOutput("@{x}", i);
00bd
Default case with leading zeros
UInt16 i = 189; DiagnosticOutput("@{x'~'}", i);
00bd
Same as above but the fillspace is somewhat useless since the unused digits of a number are always filled with leading zeros.
UInt16 i = 189; DiagnosticOutput("0x@{x}", i);
0x00bd

Default case with additional string to show that the output is of hex format.

UInt16 i = 189; DiagnosticOutput("@{8x}", i);
____00bd
Eight characters are printed. To visualize this a '_' is shown instead of a whitespace.
UInt16 i = 189; DiagnosticOutput("@{8x'~'}", i);
~~~~00bd

Int16 value is converted to a 4 byte value with leading zeros, the rest is filled with fill chars.

UInt16 i = 189; DiagnosticOutput("@{y}", i);
bd
Default case without leading zeros.
UInt16 i = 189; DiagnosticOutput("@{y'~'}", i);
bd

Same as above but fill char is ignored since the output is always only the minimum digits needed.

UInt16 i = 189; DiagnosticOutput("@{8y}", i);
______bd
Eight characters are printed. To visualize this a '_' is shown instead of a whitespace.
UInt16 i = 189; DiagnosticOutput("@{8y'~'}", i);
~~~~~~bd

Eight characters are printed. Unused digits are filled with the fill char

Int32 i = 1343443; DiagnosticOutput("@{m}", i);
1.28 MiB
The memory unit is chosen dynamically.



Formatting Floating point values

  • "@{charsBeforeComma}" defines the number of characters before the comma. If the number is too short fill characters (by default spaces) will be added in front of it. If the number does not fit however it is still printed in full length.
  • "@{.digitsAfterComma}" specifies the number of digits after the decimal point. If a negative number is passed the number of digits is automatically chosen and up to (-digitsAfterComma). The default here is -3.
  • "@{'fillcharacter'}" specifies the fill character that is used instead of spaces. This option only makes sense in combination with charsBeforeComma.
  • "@{*}" indicates that the value shall be converted to an exact string representation. This will automatically choose the right number of digits or an exponential notation; it cannot be combined with the other options.
Call Output

Comment

Float i = -4354.3; DiagnosticOutput("@", i);
-4354.3

By default up to 3 digits after the comma are printed.

Float i = -4354.3; DiagnosticOutput("@{8'~'}", i);
~~~-4354.3

8 characters before comma by using a fill char.

Float i = -4.324; DiagnosticOutput("@{.5}", i);
-4.32400

5 digits after the comma will be printed.

Float i = -4.324; DiagnosticOutput("@{.-5}", i);
-4.324

Up to 5 digits after the comma will be printed.

Float i = -0.01 / 3.0; DiagnosticOutput("@{*}", i);
-0.003333333333333334

If Float has only single precision, the number of digits will be less.



Formatting Timer values

  • Generally all rules of Formatting Floating point values apply.
  • "@{ms}" outputs the value in milliseconds. This is also the default. Note that this parameter has to come first before any other ones.
  • "@{s}" outputs the value in seconds. Note that this parameter has to come first before any other ones.
  • "@{ns}" outputs the value in nanoseconds. Note that this parameter has to come first before any other ones.
  • "@{ps}" outputs the value in 1/seconds (per second). Note that this parameter has to come first before any other ones.
Call Output

Comment

TimeValue t = Milliseconds(45.254); DiagnosticOutput("@", t);
45.3 ms

By default up to 1 digit after the comma is printed.

TimeValue t = Milliseconds(45.254); DiagnosticOutput("@{8.3'%'}", t);
%%%%%%45.254 ms

Fill chars and format rules work like for regular float values.

TimeValue t = Milliseconds(45.254); DiagnosticOutput("@{s.3}", t);
0.045 s

An output unit can be specified. It must be the first parameter of the formatting string.



Formatting Pointer values

  • Generally all rules of Formatting Integer values apply.
  • You need to cast your pointer to (void*) or (const void*). Otherwise the content of the pointer will be printed.
  • @x is automatically the default.
Call Output

Comment

void* ptr = (void*)0x04; DiagnosticOutput("@", ptr);
00000004

Note that either 8 or 16 characters are printed depending on if this is a 32-bit or 64-bit build.

void* ptr = (void*)0x04; DiagnosticOutput("0x@", ptr);
0x00000004

As before with 0x manually added.

void* ptr = (void*)0x04; DiagnosticOutput("0x@{y}", ptr);
0x4

As before but without leading zeros.

Int i = 15; Int* ptr = &i; DiagnosticOutput("@", ptr);
15

If the pointer is not void the content is printed.



Formatting Mixed types

If you want to output types like Data, DataContainer, HashMap<..., Data> etc. the problem is that each data type may support a different syntax. E.g. a formatting statement ".1" is valid for a float, but not valid for an integer. To solve this problem you can address the type that the statement was made for.
The syntax is:

@{type1:statement1|type2:statement2|...}

Possible types are "float", "int", "timer" or further custom enhancements of your data types.

Call

Output

DataContainer bc;
bc.Set(1000, Data((Int64)5);
bc.Set(1001, Data(Vector64(4.0));
DiagnosticOutput("@{float:.6|int:8'o'}", bc);
1000: <maxon.Int64> ooooooo5
1001: <maxon.Vector64> (4.000000,4.000000,4.000000)

Int
maxon::Int Int
Definition: ge_sys_math.h:64
maxon
The maxon namespace contains all declarations of the MAXON API.
Definition: c4d_basedocument.h:15
UInt32
maxon::UInt32 UInt32
Definition: ge_sys_math.h:61
Float
maxon::Float Float
Definition: ge_sys_math.h:66
Vector64
maxon::Vec3< maxon::Float64, 1 > Vector64
Definition: ge_math.h:143
DiagnosticOutput
#define DiagnosticOutput(formatString,...)
Definition: debugdiagnostics.h:167
UInt16
maxon::UInt16 UInt16
Definition: ge_sys_math.h:59
Int32
maxon::Int32 Int32
Definition: ge_sys_math.h:60
Int64
maxon::Int64 Int64
Definition: ge_sys_math.h:62
Char
maxon::Char Char
Definition: ge_sys_math.h:56