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”:

#include <QtCore/QCoreApplication> #include <stdio.h> #include <iostream> using namespace std; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); printf("Hello, World!\n"); cout << "Hello Universe!\n"; return a.exec(); }

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:

Value Escape sequence
newline \n
horizontal tab \t
vertical tab \v
backspace \b
carriage return \r
form feed \f
alert \a
backslash \\
question mark ? or \?
single quote \'
double quote \"
the null character \0
octal number "ON" \oON
hexadecimal number "HXN" \xHXN
Unicode (UTF-8) character "xxxx" \uxxxx
Unicode (UTF-16) character "xxxxxxxx" \Uxxxxxxxx

Several of these character sequences have an influence on the position of the following output on the screen (or inside the current window etc.). I'll leave it to you to experiment a little. A small demonstration program is available on the Microsoft Visual Studio C++ reference website about C++ character literals.

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

Here is a short example of how this is used:

#include <QCoreApplication> #include <stdio.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); char myoutput [60]; int stringlength, x=4, y=10; stringlength = sprintf(myoutput, "%d plus %d equals %d", x, y, x+y); printf ("[%s] is a string that is %d characters long.\n", myoutput, stringlength); return a.exec(); }

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.

The return value can usually be ignored.

Here is a short example for using “putc”:

#include <QCoreApplication> #include <stdio.h> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int c1='A', c2='B', c3='C', nl='\n'; putc(c1, stdout); putc(c2, stdout); putc(c3, stdout); putc(nl, stdout); return a.exec(); }

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.

Final words

That's it for the current part of this tutorial.

The code can be found in the "Console_Output" subdirectory of the git repository on github. You can clone the complete tutorial repository if you already have git or GitHub Desktop installed on your computer, or you can download it as a ZIP file.

The next part of the tutorial will deal with the basic forms of data input.