Learn C++ with Qt, Part 003: Console Output

In this part of the tutorial, we’ll cover the basic
output functions for simple console (terminal) programs.

The most common operating systems today use graphical user interfaces, so you might
ask why I'm writing about simple terminal output here.

This classic form of output has several advantages:

it is based on simple printed output, similar to the output on a classic mechanical typewriter, which makes it easy to understand

it is still used often for debugging and for embedded systems

it can be used to write data to different output channels like a screen, a printer or a file with very little modification to the code of the program

More modern forms of output specialized for graphical user interfaces are more complex and often cannot be used for different output channels without bigger code modifications.Once you know the basic forms of output, the more complex forms are easier to understand.

Console / Terminal program

Before we start properly, you should know what I mean by “console” or “terminal”
programs or applications.

In today’s operating systems with graphical user interfaces (GUIs),
programs designed for direct interaction with a user open up their
own application window. The input and output of the application happens inside
this window.

In contrast to this, a console or terminal program is started from the command
line inside a terminal window. The terminal window in itself is an application
that simulates the behavior of a classic, text-only physical terminal combined
with a command interpreter.

This is the kind of interaction that was normal for any computer user up to
the beginning of the 1980s, especially the users of mainframe computers. Back
in the 1950s and 1960s, the terminals didn’t even have a CRT or LCD display,
but used printer mechanics instead.

Terminal programs run inside this simulated environment. The “Hello World”
program from before and the upcoming examples use the Qt “QCoreApplication”
object. This automatically adds the terminal window with its integrated
environment to the current program, which allows us to use the classic forms of output
and input which were originally developed for terminal programs.

Console text output of strings

Let’s start out with a variation of the “Hello World”
program from the second part of the tutorial which I’ve named “Console_IO”:

As you can see, I’ve combined the two different
versions for text output: the “printf” function and the stream-based “cout”
function (which have already been used in the "Hello World" program).

Both related function / object libraries (“stdio.h” and
“iostream”) are included, so both functions can be used within the same
program. This principle is also used to add more functions from different
function libraries to a program – just include the library call and make sure
that the library file can be found in one of the default folders for function
libraries.

When you run this program, it opens a console window
and prints out the text “Hello, World!” followed by “Hello Universe!” in two
different lines. The program can be ended by closing its window.

Control characters

The “Console_IO” program from above uses the special
character “\n” as part of the string of characters which are printed to the
screen within the console window. You cannot see these characters however, they
seem to be invisible.

This is because “\n” describes a special “control”
character that is part of the unprintable control characters in the ASCII
character table (in this case the new line or carriage return character, depending on the operating system). These kinds of characters were originally defined
in order to tell the printer or terminal to perform specific actions as part of
its output.

The newline character which is referred to by the
string “\n” tells the printer or terminal to go to a new line and continue the
output there. So any text that is printed after that appears in the next line.
If you delete the newline character from the string, the following text is
printed on the same line, up until the physical end of the line, when the
line break occurs automatically.

Go ahead and change the text after “printf” and “cout”
in the “Console_IO” program. Try to add additional “\n” characters or delete
“\n” from the strings, and run the program anew after each change. You will
quickly see how the text output works.

With the stream-based “cout” function you can also use
the stream “manipulator” named “endl” to mark the end of an output line:

Cout << “Hello” << endl;
Cout << “World” << endl;

While the output is identical to using “\n”, the
“endl” modifier has an additional side effect.

In most modern systems, input and output streams are
buffered. This means that any data which is added to the stream is first stored
in a temporary cache memory before it is actually read by (for input) or written
to (for output) the individual target. This allows data to be read, computed or
written at different speeds. For example, a modern computer can compute values
much quicker than these values can be written to a file on a harddisk, so the
buffer helps to synchronize the output stream and helps that no data is lost in
the transfer process.

The “endl” modifier forces the buffer to be emptied
along with switching to a new line. This means that any text that was stored in
the buffer before will be written to the target. After that, the buffer will be
completely empty, before being filled again with further output data.

This can be useful when the output target is a file, a
physical printer or a database.

Here are some other control characters for the
so-called “escape sequences” which can be included in an output string:

Different output channels for text

In C++, there are some additional output channels for text
output streams that can be used in the same way as “cout”, the default console
output:

cerr: this is the default output for error messages.
It is usually linked to the same text console as “cout”, but can be redirected,
so that the error messages will appear in a different place.

clog: this channel is used for logging information
about the different activities of an application. This can be used to track
what an application is doing and where and when errors occur. It is often
redirected to a text file, so any log information from this channel is
automatically written into the file.

file redirection: any text output stream can be
redirected into a file object. This is an easy way to save text output
permanently and use it again later on.

Formatted output

So far, our text output has been straight forward,
character after character. While the classic output functions mentioned above
don’t allow complex text formatting like in a word processing application (with
different fonts, text sizes, text styles etc.), it is possible to use a
different output function which offers some basic formatted output: the
“sprintf” function from the C programming language.

Its formatting capabilities are limited to controlling
the positioning and width of text output, especially regarding the output of
values from variables as part of text output. The syntax for "sprintf" looks like this:

int sprintf ( char * str, const char * format, var1, ... , varN );

I’ll cover variables and functions in more detail
later in this tutorial, so here is just a quick run-down for the “sprintf”
output function:

it is a function with a return value that returns
the length of the formatted string

the first parameter “str” is a string variable in
which the formatted output is stored (this has to be printed with “printf” or
“cout” afterwards)

the second parameter is a string with placeholders
that controls the formatting of the output

the additional parameters are variables whose values
replace the related place holders of the formatting string in the final output
string

In the example above, the “%d” placeholders for
decimal, numeric values are replaced by the current values of “x” (4), “y” (10)
and “x+y” (14) by the “sprintf” function. The resulting string is stored inside
the variable “myoutput”, and the length of this string is returned by the
function and stored in the variable “stringlength”.

At the end, the “printf” function then prints the
formatted string between two square brackets, followed by some additional text
including the length of the string.

The output of this program should look like this:

[4 plus 10 equals 14] is a string that is 19
characters long.

If you get a warning for “sprintf” when you try to run
the above example program, you can ignore this for the moment. On a Windows PC,
when you are using Microsoft Visual Studio / Visual C++ together with Qt, you
can use “sprintf_s” instead in order to avoid the warting.

Different placeholders are used in the formatting
string, depending on the type of variable that holds the values which should be
included in the final output string:

“%s” for text strings

“%c” for single characters

“%d” for integer values (integer numbers)

“%f” for real or double values (floating point
numbers)

Console output for single characters

Up until now, we have only printed text strings made
up of several characters and words. But occasionally we also need the option to
print a single character, especially the current values of single character
variables.

This can be done with the put character function
“putc”. The syntax of this function is as follows:

int putc(int c, FILE *file);

The first parameter “c” receives the value of the
single character that should be written to the output channel. The second parameter
“file” points to the output channel. While the syntax seems to point out that
this is a file, it actually is an output stream. This can be a text file, a
window or monitor or any other kind of output stream.

As usual, a console window is initialized and opened
here. Then the “putc” function writes all the characters which are stored
inside the variables “c1” to “c3” to the output stream, followed by a “new
line” character. This produces the output “ABC”.

In this example, the output stream is "stdout", the standard output channel. In a console application, this is the "inside" of the current application window.

All text which is printed inside the console (terminal) window automatically starts at the current location of the text cursor. In a
standard "western" operating system environment, the text is written
from left to right, and the text cursor is automatically moved to the
next position in the same line. At the end of the line, it is
automatically moved to the beginning of the next line. This behavior is
the same no matter how many characters are written to the output stream.

The only way to get the cursor to move "backwards" or up or down from its current position is to use the special escape sequence characters like "backspace" (see table above) as part of the printed output.