TextStream & Command Line Interface
Global IO Functions
Convenience functions for simple console I/O.
print(String text)- Writes
textfollowed by a newline. - Equivalent to
cout.writeLine(text).
- Writes
readLine() -> String- Reads a line from standard input.
- Equivalent to
cin.readLine().
input(String prompt = "") -> String- Writes
promptwithout a newline and reads a line from standard input, - as in Python.
- Equivalent to
cout.write(prompt),cout.flush(), andcin.readLine().
- Writes
BasicStream
Interface as base for Text*Stream and Byte*Stream.
stream.isOpen() -> Boolstream.close()
TextStream
Interface for input / output of text, derived from TextInStream and TextOutStream.
TextOutStream
Interface for writing text, derived from BasicStream.
cout.write("...")without newline.cout.writeLine("...")with newline, default argument is""(i.e. an empty line).
cout.write(Char8/16/32 codePoint)writes a single Unicode symbolcout.write(Int number)writes a numbercout.write(Float floatingPointNumber)
cout.write(UInt8/16/32/64 hexNumber)writes a number in hexadecimal format, without prefix, the width is derived from the type:UInt8->"2a"UInt16->"002a"UInt32->"0000002a"UInt64->"000000000000002a"
cout.write(String prefix, UInt8/16/32/64 hexNumber)writes a number in hexadecimal format with the given prefix (e.g."0x"or"$")
out.flush()writes the data buffer to the operating system.- This protects against data loss in the event of a program crash.
out.flushAndSync()callsflush(), then- calls
fsync()to write the kernel buffers to the file system and then to the hard disk/SSD (the write cache should be written/cleared, too). - This protects against data loss in the event of a program or system crash.
- calls
Cache:
Byte* outBuffer
The output buffer is stored as pointer, to allow:- a single common buffer (for files) as well as two separate buffers for input and output (for network connections),
- a dedicated buffer (for TextFile) as well as a String as backing store (for StringStream).
Int outPositionInt outCapacity
virtual writeRaw(Span<Byte> src)- With TextFile: copies all bytes to the underlying File.
- With StringStream:
- on
flush(): update the size of the buffer string, - on
writeRaw()with buffer capacity reached:- update the size of the buffer string,
- allocate a new, bigger buffer string,
- copy all bytes from the old buffer string to the new one,
- adjust
outBuffer=newBufferString.data(),outPosition=newBufferString.size(), andoutCapacity=newBufferString.capacity.
- on
Operator <<
Output stream operator <<, similar to C++ iostreams:
cout << "Text"
Int value = 1
cout << value
But TextStreams are stateless only, i.e. there are no “state manipulators”.
endl does not flush, you need to flush explicitly:
cout << "Text" << endlcout << "Text" << endl << flush
Using output descriptors to control the behaviour:
cout << Hex(address)
cout << Quoted(name)
cout << Escaped(text)
TextInStream
Interface for reading text, derived from BasicStream.
cin.read() -> Stringreads- everything from the input buffer (if not empty),
- or (otherwise) everything from the kernel buffer/cache:
- With pipes/sockets this is everything currently in the kernel pipe/socket buffer (typically up to 64 KB).
- With files this is everything currently in the kernel “read ahead” cache (typically 64 to 256 KB).
- Blocks when this buffer/cache is empty.
- Only when the pipe/socket is closed / end of file is reached, and no data is buffered anymore, then it returns
"".
cin.read(minimum..) -> Stringreads everything that is immediately available,- blocks until at least
minimumcharacters are read. - Reads everything from the input buffer (if not empty),
- or (otherwise) everything from the kernel buffer/cache:
- With pipes/sockets this is everything currently in the kernel pipe/socket buffer (typically up to 64 KB).
- With files this is everything currently in the kernel “read ahead” cache (typically 64 to 256 KB).
- Returns
""when no data is buffered anymore (then maybe the pipe/socket is closed / the end of file is reached). - With
minimum=0:- Never blocks.
- Meant for polling / busy loops only, so rarely appropriate.
- You need to check
atEnd()separately!- As you cannot distinguish “no data available” from EOF or pipe/socket closed.
- blocks until at least
cin.readAll() -> Stringreads everything until the end of the file.- With pipes/sockets, it blocks until the pipe/socket is closed.
cin.readLine() -> Stringreads until newline (or end of file).- The newline character is removed from the line.
\n,\r,\r\nare recognized as (a single) newline.- (Maybe even
\n\rfrom Acorn RISC OS “spooled text”, andNEL/U+0085from EBCDIC/IBM.)
- With pipes/sockets it blocks until a line is available (or pipe/socket is closed).
- When the end of file is reached, then it returns
"". - But as empty lines are also read as
"", you need to checkatEnd()here.
- The newline character is removed from the line.
cin.readGraphemeCluster() -> Stringreads a single grapheme cluster (mostly a character).- Returns a
String, as UTF-8 “characters”/grapheme clusters may consist of multiple code points (therefore called a “grapheme cluster”). - With pipes/sockets it blocks until a character is available (or the pipe/socket is closed).
- When the end of file is reached, then it returns
"". - Unicode variant of
.cin.readChar() -> Char
- Returns a
cin.readCodePoint() -> Char32reads a single Unicode code point (asChar32).- But beware: some grapheme clusters, like emoji, consist of multiple code points.
- When the end of file is reached, then it returns
-1.
cin.atEnd()(instead of)cin.isEof()- returns
Trueif- the end of the file is reached (or the pipe/socket is closed),
- and no data is buffered anymore (neither in the
istreamuser-level cache, nor in the kernel cache/buffer),
- Typically necessary to call this function when
cin.read()orcin.readLine()return"".
- returns
Operator >>
Input stream operators >>, similar to C++ iostreams:
Int i
cin >> i
Float f
cin >> f
Char32 codePoint
cin >> codePoint
String word
cin >> word
But TextStreams are stateless only, i.e. there are no “state manipulators”.
Using input descriptors to control the behaviour:
UInt address
cin >> Hex(address)
String grapheme
cin >> GraphemeCluster(grapheme)
String line
cin >> Line(line)
Technically realized as:
class GraphemeCluster {
String& storage
}
operator (TextInStream stream) >> (GraphemeCluster graphemeCluster) {
graphemeCluster.storage = stream.readGraphemeCluster()
}
class Line {
String& storage
}
operator (TextInStream stream) >> (Line line) {
line.storage = stream.readLine()
}
TextFile
Class derived from TextStream:
TextFile::open("Test.txt") -> FileTextFile::create("Test.txt") -> FileTextFile::openOrCreate("Test.txt") -> File
textFile.path() -> StringtextFile.name() -> String
StringStream
Class derived from TextStream:
StringStream stringStream(String content)StringStream stringStream(Int capacity = 0)