Stream Examples


Implicit Separator

By default, printed values are implicitly separated by whitespace. The implicit separator character (space/blank) is a separator not a terminator for output. The rules for implicitly adding the separator are:

sout | 1 | 2 | 3;
1 2 3
sout | '1' | '2' | '3';
123
sout | 1 | "" | 2 | "" | 3;
123
sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
		| 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";
1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥"
		| 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;
x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx";
x`1`x'2'x"3"x:4:x 5 x	6	x
sout | "x (" | 1 | ") x" | 2 | ", x" | 3 | ":x:" | 4;
x (1) x 2, x 3:x:4

Separation Manipulators

The following manipulators control implicit output separation. The effect of these manipulators is global for an output stream (except sepOn and sepOff).

sepSet( sout, ", $" );						// set separator from " " to ", \$"
sout | 1 | 2 | 3 | " \"" | sep | "\"";
1, $2, $3 ", $"
sepSet( sout, " " );						// reset separator to " "
sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"";
1 2 3 " "
char store[sepSize];						// sepSize is the maximum separator size
strcpy( store, sepGet( sout ) );			// copy current separator
sepSet( sout, "_" );						// change separator to underscore
sout | 1 | 2 | 3;
1_2_3
sepSet( sout, store );						// change separator back to original
sout | 1 | 2 | 3;
1 2 3
sepSetTuple( sout, " " );					// set tuple separator from ", " to " "
sout | t1 | t2 | " \"" | sepTuple | "\"";
1 2 3 4 5 6 " "
sepSetTuple( sout, ", " );					// reset tuple separator to ", "
sout | t1 | t2 | " \"" | sepGetTuple( sout ) | "\"";
1, 2, 3 4, 5, 6 ", "
sout | sepDisable | 1 | 2 | 3;				// turn off implicit separator
123
sout | sepEnable | 1 | 2 | 3;				// turn on implicit separator
1 2 3
sout | 1 | sepOff | 2 | 3;					// turn off implicit separator for the next item
12 3
sout | sepDisable | 1 | sepOn | 2 | 3;		// turn on implicit separator for the next item
1 23
sout | t1 | sepOff | t2;					// turn off implicit separator for the next item
1, 2, 34, 5, 6
sout | sepOn | 1 | 2 | 3 | sepOn;			// sepOn does nothing at start/end of line
1 2 3
sout | sep | 1 | 2 | 3 | sep ;				// use sep to print separator at start/end of line
∪︀1 2 3∪︀

Newline Manipulators

The following manipulators control newline separation for input and output. For input:

  1. nl scans characters until the next newline character, i.e., ignore the remaining characters in the line.
  2. nlOn reads the newline character, when reading single characters.
  3. nlOff does not read the newline character, when reading single characters.

For example, in:

sin | i | nl | j;
1 2
3

variable i is assigned 1, the 2 is skipped, and variable j is assigned 3. For output:

  1. nl inserts a newline.
    sout | nl; 								// only print newline
    sout | 2; 								// implicit newline
    sout | 3 | nl | 4 | nl; 				// terminating nl merged with implicit newline
    sout | 5 | nl | nl; 					// again terminating nl merged with implicit newline
    sout | 6; 								// implicit newline
    
    2
    3
    4
    5
    
    6
    
    Note, a terminating nl is merged (overrides) with the implicit newline at the end of the sout expression, otherwise it is impossible to to print a single newline
  2. nlOn implicitly prints a newline at the end of each output expression.
  3. nlOff does not implicitly print a newline at the end of each output expression.

Output Value Manipulators

The following manipulators control formatting of output values (printing), and only affect the format of the argument.

  1. bin( integer ) print value in base 2 preceded by 0b/0B.
    sout | bin( 0 ) | bin( 27HH ) | bin( 27H ) | bin( 27 ) | bin( 27L );
    0b0 0b11011 0b11011 0b11011 0b11011
    sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L );
    0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b(58 1s)100101
    
  2. oct( integer ) print value in base 8 preceded by 0.
    sout | oct( 0 ) | oct( 27HH ) | oct( 27H ) | oct( 27 ) | oct( 27L );
    0 033 033 033 033
    sout | oct( -27HH ) | oct( -27H ) | oct( -27 ) | oct( -27L );
    0345 0177745 037777777745 01777777777777777777745
    
    Note, octal 0 is not preceded by 0 to prevent confusion.
  3. hex( integer / floating-point ) print value in base 16 preceded by 0x/0X.
    sout | hex( 0 ) | hex( 27HH ) | hex( 27H ) | hex( 27 ) | hex( 27L );
    0 0x1b 0x1b 0x1b 0x1b
    sout | hex( -27HH ) | hex( -27H ) | hex( -27 ) | hex( -27L );
    0xe5 0xffe5 0xffffffe5 0xffffffffffffffe5
    
    sout | hex( 0.0 ) | hex( 27.5F ) | hex( 27.5 ) | hex( 27.5L );
    0x0.p+0 0x1.b8p+4 0x1.b8p+4 0xd.cp+1
    sout | hex( -27.5F ) | hex( -27.5 ) | hex( -27.5L );
    -0x1.b8p+4 -0x1.b8p+4 -0xd.cp+1
    
  4. sci( floating-point ) print value in scientific notation with exponent. Default is 6 digits of precision.
    sout | sci( 0.0 ) | sci( 27.5 ) | sci( -27.5 );
    0.000000e+00 2.750000e+01 -2.750000e+01
    
  5. upcase( bin / hex / floating-point ) print letters in a value in upper case. Lower case is the default.
    sout | upcase( bin( 27 ) ) | upcase( hex( 27 ) ) | upcase( 27.5e-10 ) | upcase( hex( 27.5 ) );
    0B11011 0X1B 2.75E-09 0X1.B8P+4
    
  6. nobase( integer ) do not precede bin, oct, hex with 0b/0B, 0, or 0x/0X. Printing the base is the default.
    sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) );
    11011 33 1b
    
  7. nodp( floating-point ) do not print a decimal point if there are no fractional digits. Printing a decimal point is the default, if there are no fractional digits.
    sout | 0. | nodp( 0. ) | 27.0 | nodp( 27.0 ) | nodp( 27.5 );
    0.0 0 27.0 27 27.5
    
  8. sign( integer / floating-point ) prefix with plus or minus sign (+ or -). Only printing the minus sign is the default.
    sout | sign( 27 ) | sign( -27 ) | sign( 27. ) | sign( -27. ) | sign( 27.5 ) | sign( -27.5 );
    +27 -27 +27.0 -27.0 +27.5 -27.5
    
  9. wd( unsigned char minimum, T val ), wd( unsigned char minimum, unsigned char precision, T val ) For all types, minimum is the minimum number of printed characters. If the value is shorter than the minimum, it is padded on the right with spaces.
    sout | wd( 4, 34) | wd( 3, 34 ) | wd( 2, 34 );
    sout | wd( 10, 4.) | wd( 9, 4. ) | wd( 8, 4. );
    sout | wd( 4, "ab" ) | wd( 3, "ab" ) | wd( 2, "ab" );
      34  34 34
      4.000000  4.000000 4.000000
      ab  ab ab
    
    If the value is larger, it is printed without truncation, ignoring the minimum.
    sout | wd( 4, 34567 ) | wd( 3, 34567 ) | wd( 2, 34567 );
    sout | wd( 4, 3456. ) | wd( 3, 3456. ) | wd( 2, 3456. );
    sout | wd( 4, "abcde" ) | wd( 3, "abcde" ) | wd( 2,"abcde" );
    34567 34567 34567
    3456. 3456. 3456.
    abcde abcde abcde
    
    For integer types, precision is the minimum number of printed digits. If the value is shorter, it is padded on the left with leading zeros.
    sout | wd( 4,3, 34 ) | wd( 8,4, 34 ) | wd( 10,10, 34 );
     034     0034 0000000034
    
    If the value is larger, it is printed without truncation, ignoring the precision.
    sout | wd( 4,1, 3456 ) | wd( 8,2, 3456 ) | wd( 10,3, 3456 );
    3456     3456       3456
    
    If precision is 0, nothing is printed for zero. If precision is greater than the minimum, it becomes the minimum.
    sout | wd( 4,0, 0 ) | wd( 3,10, 34 );
         0000000034
    
    For floating-point types, precision is the minimum number of digits after the decimal point.
    sout | wd( 6,3, 27.5 ) | wd( 8,1, 27.5 ) | wd( 8,0, 27.5 ) | wd( 3,8, 27.5 );
    27.500     27.5      28. 27.50000000
    
    For the C-string type, precision is the maximum number of printed characters, so the string is truncared if it exceeds the maximum.
    sout | wd( 6,8, "abcd" ) | wd( 6,8, "abcdefghijk" ) | wd( 6,3, "abcd" );
      abcd abcdefgh    abc
    
  10. ws( unsigned char minimum, unsigned char significant, floating-point ) For floating-point type, minimum is the same as for manipulator wd, but significant is the maximum number of significant digits to be printed for both the integer and fractions (versus only the fraction for wd). If a value's significant digits is greater than significant, the last significant digit is rounded up.
    sout | ws(6,6, 234.567) | ws(6,5, 234.567) | ws(6,4, 234.567) | ws(6,3, 234.567);
    234.567 234.57  234.6    235
    
    If a value's magnitude is greater than significant, the value is printed in scientific notation with the specified number of significant digits.
    sout | ws(6,6, 234567.) | ws(6,5, 234567.) | ws(6,4, 234567.) | ws(6,3, 234567.);
    234567. 2.3457e+05 2.346e+05 2.35e+05
    
    If significant is greater than minimum, it defines the number of printed characters.
    sout | ws(3,6, 234567.) | ws(4,6, 234567.) | ws(5,6, 234567.) | ws(6,6, 234567.);
    234567. 234567. 234567. 234567.
    
  11. left( field-width ) left justify within the given field.
    sout | left(wd(4, 27)) | left(wd(10, 27.)) | left(wd(10, 27.5)) | left(wd(4,3, 27)) | left(wd(10,3, 27.5));
    27   27.000000  27.500000  027  27.500    
    
  12. pad0( field-width ) left pad with zeroes (0).
    sout | pad0( wd( 4, 27 ) ) | pad0( wd( 4,3, 27 ) ) | pad0( wd( 8,3, 27.5 ) );
    0027  027 0027.500
    

Input Value Manipulators

The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable. For _Bool type, the constants are true and false. For integral types, any number of digits, optionally preceded by a sign (+ or -), where a

For floating-point types, any number of decimal digits, optionally preceded by a sign (+ or -), optionally containing a decimal point, and optionally followed by an exponent, e or E, with signed (optional) decimal digits. Floating-point values can also be written in hexadecimal format preceded by 0x or 0X with hexadecimal digits and exponent denoted by p or P. For the C-string type, the input values are not the same as C-string constants, i.e., double quotes bracketing arbitrary text with escape sequences. Instead, the next sequence of non-whitespace characters are read, and the input sequence is terminated with delimiter '\0'. The string variable must be large enough to contain the input sequence.

The following manipulators control formatting of input values (reading), and only affect the format of the argument.

  1. skip( const char * pattern ) / skip( unsigned int length ) / const char * pattern The argument defines a pattern or length. The pattern is composed of white-space and non-white-space characters, where any white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character. The length is composed of the next $N$ characters, including the newline character. If the match successes, the input characters are discarded, and input continues with the next character. If the match fails, the input characters are left unread.
    char sk[$\,$] = "abc";
    sin | "abc " | skip( sk ) | skip( 5 );	// match input sequence
    abc   
    abc  
    xx
    
  2. wdi( unsigned int maximum, T & val ) For all types except char, maximum is the maximum number of characters read for the current operation.
    char s[10];   int i;   double d;   
    sin | wdi( 4, s ) | wdi( 3, i ) | wdi( 8, d );  // c == "abcd", i == 123, d == 3.456E+2
    abcd1233.456E+2
    
    Note, input wdi cannot be overloaded with output wd because both have the same parameters but return different types. Currently, C∀ cannot distinguish between these two manipulators in the middle of an sout/sin expression based on return type.
  3. ignore( T & val ) For all types, the data is read from the stream depending on the argument type but ignored, \ie it is not stored in the argument.
    double d;
    sin | ignore( d );						// d is unchanged
      -75.35e-4 25
    
  4. incl( const char * scanset, char * s ) For the C-string type, the argument defines a scanset that matches any number of characters in the set. Matching characters are read into the C string and null terminated.
    char s[10];
    sin | incl( "abc", s );
    bcaxyz
    
  5. excl( const char * scanset, char * s ) For the C-string type, the argument defines a scanset that matches any number of characters not in the set. Non-matching characters are read into the C string and null terminated.
    char s[10];
    sin | excl( "abc", s );
    xyzbca