C++ Tutorial

Standardausgabe

Ausgabestream cout

Für die Ausgabe auf die Standardausgabe, dies ist in der Regel der Bildschirm, wird im Allgemeinen der Ausgabestream cout aus der C++-Standardbibliothek verwendet.

Damit der Compiler cout kennt, ist eine Datei, die sogenannte Include- oder Header-Datei, einzubinden. Für cout ist dies die Datei <iostream>. Das Einbinden erfolgt durch die Präprozessor-Direktive

#include <iostream>

Dabei ist zu beachten, dass am Ende der Präprozessor-Direktive kein Semikolon steht! Mehr zu den Präprozessor-Direktiven, die alle mit dem Zeichen '#' beginnen, später.

Auszugebenden Texte und Daten werden mit dem Operator << in den Ausgabestream übertragen.

std::cout << AUSGABE1 [<< AUSGABE2 [<<...]];

Das Präfix std:: teilt dem Compiler mit, dass das Ausgabestream-Objekt cout im Namensraum der Standardbibliothek liegt. Mehr zu den Namensräumen ebenfalls in einem späteren Kapitel.

Anstelle bei jeder Ausgabe das Präfix std:: anzugeben, kann vor der ersten Verwendung von cout die nachfolgende using-Anweisung eingefügt werden:

using std::cout;

1: // Datei iostream einbinden
2: #include <iostream>
3: // using Anweisung
4: using std::cout;
5:
6: int main ()
7: {
8:    cout << ...; // hier steht dann die Ausgabe
9: }

Text- und Datenausgabe

Auszugebende Texte (Strings) und Daten werden durch Verkettung mit dem Operator << in den Ausgabestream übertragen, wobei Texte in Anführungszeichen eingeschlossen werden.

Am Ende einer Ausgabe erfolgt kein automatischer Zeilenumbruch. Soll nach einer Ausgabe eine neue Zeile begonnen werden, ist eine Escape-Sequenz auszugeben, die im nächsten Abschnitt erläutert wird.

1: #include <iostream>
2:
3: int main()
4:{
5:    // Eine Variable definieren und initialisieren
6:    // Variablen werden im naechsten Kapitel behandelt
7:    int var = 10;
8:    // Ausgabe eines Textes und des Datums var
9:    std::cout << "var hat den Wert " << var;
10: }

var hat den Wert 10

Für die Formatierung der Ausgabe stehen diverse Manipulatoren zur Verfügung, wie z.B. setw(n) um ein Datum mit n Stellen auszugeben. Auf der Seite https://en.cppreference.com ist unter dem Stichwort Input/output manipulators eine Übersicht der Manipulatoren zu finden.

Im weiteren Verlaufe des Tutorials werden für die Formatierung der Ausgabe die neueren Bibliotheksfunktionen format(), print() und println() verwendet. format() legt die formatiert auszugebenden Texte und Daten in einem String-Objekt ab, welches dann mittels cout ausgegeben werden kann. print() bzw. println() geben die Daten direkt in einen Ausgabestream aus, wobei println() nach der Ausgabe einen Zeilenvorschub ausgibt und print() nicht.

Wird die Bibliotheksfunktion format() verwendet ist die Header-Datei <format> einzubinden und für die Bibliotheksfunktionen print() bzw. println() die Header-Datei <print>.

Die Funktionen besitzen folgende Syntax:

std::string std::format(std::format_string fmt [, Args&&... args]);
void std::print([std::FILE* stream,] std::format_string fmt [,Args&&... args]);
void std::println([std::FILE* stream,] std::format_string fmt [,Args&&... args]);

Der optionale Parameter stream bei print() bzw. println() legt den für die Ausgabe zu verwendenden Ausgabestream fest und ist in der Regel ein Dateistream (siehe dazu Kapitel Dateizugriffe).

Der Parameter fmt ist ein in Anführungszeichen eingeschlossener Formatierungsstring. Er enthält den auszugebenden Text sowie Platzhalter { } für die auszugebenden Daten. Enthält der Text ebenfalls geschweifte Klammern, sind diese zu verdoppeln.

Der letzte optionale Parameter args ist eine kommaseparierte Liste mit den auszugebenden Daten. Dabei wird standardmäßig das erste Datum in der Liste dem ersten Platzhalter { } im Formatierungsstring zugewiesen, das zweite Datum dem zweiten Platzhalter usw.

Im nachfolgenden Beispiel erzeugen alle drei Anweisungen die gleiche Ausgabe.

1: #include <iostream>
2: #include <format>
3: #include <print>
4:
5: int main()
6: {
7:    // Eine Variable definieren und initialisieren
8:    // Variablen werden im naechsten Kapitel behandelt
9:    int var = 10;
10:
11:   // Ausgabe ueber einen String mittels format()
12:   std::cout << std::format("1: var hat den Wert {}\n",var);
13:
14:   // Ausgabe mittels println, wobei der Ausgabestream
15:   // std::cout explizit angegeben wird
16:   std::println(std::cout,"2: var hat den Wert {}",var);
17:
18:   // Ausgabe mittels println mit implizitem std::cout
19:   // Ausgabestream
20:   std::println("3: var hat den Wert {}\n",var);
21: }

1: var hat den Wert 10
2: var hat den Wert 10
3: var hat den Wert 10

Die standardmäßige Zuordnung, Platzhalter zu Datum, kann durch Angabe eines Indexes innerhalb des Platzhalters überschrieben werden, wobei das erste Datum in der Liste den Index 0 besitzt.

1: #include <print>
2:
3: int main()
4: {
5:    std::println("Die Wurzel aus {} ist {{ {} }}", 2, 1.41);
6:    std::println("{1} ist die Wurzel aus {0}\n", 2, 1.41);
7: }

Die Wurzel aus 2 ist { 1.41 }
1.41 ist die Wurzel aus 2

Außer einem Index kann der Platzhalter { } Formatspezifizierer enthalten, welche durch einen Doppelpunkt eingeleitet werden. 

:[[fill]align][sign][#][0][width][.precision][type]

width: Legt die minimale Stellenanzahl des auszugebenden Datums fest. width ist entweder ein positiver Integer-Wert oder ein weiterer Platzhalter, um die Stellenanzahl dynamisch festzulegen (siehe Zeile 4).

1: // Anzahl Stellen ueber Variable definieren
2: auto anzStellen = 6;
3: std::println("*{:5}*",10);
4: std::println("*{:{}}*",10,anzStellen);

*   10*
*    10*

[fill]align: align bestimmt die Ausrichtung der Ausgabe und fill definiert das Füllzeichen, das für nicht belegte Stellen verwendet wird. Standardmäßig wird für fill ein Leerzeichen verwendet.

align
Ausrichtung
<
linksbündig; Standard für nicht-numerische Daten
>
rechtbündig; Standard für numerische Daten
 ^
zentriert
1: std::println("*{:~<5}*", 10);
2: std::println("*{:>{}}*", 10, 6);
3: std::println("{:#^20}", "Text zentriert");

*10~~~*
*    10*
###Text zentriert###

sign: Legt fest, wie das Vorzeichen bei numerischen Daten auszugeben ist.

sign
Vorzeichen
-
Vorzeichen nur bei negativen Werten (Standard)
+
Vorzeichen bei allen Werten
Leerzeichen
Minus-Zeichen bei negativen Werten, Leerzeichen bei positiven Werten
1: std::println("*{:<-5}*", -10);
2: std::println("*{:<+5}*", 10);
3: std::println("*{:< 5}*", -10);
4: std::println("*{:< 5}*", 10);

*-10  *
*+10  *
*-10  *
* 10  *

#: Gibt bei Integer-Daten ein Präfix für das bei Ausgabe verwendete Zahlensystem aus (siehe nachfolgenden Formatspezifizierer type).

ausgegebener Präfix
Verwendetes Zahlensystem
0x bzw. 0X
Ausgabe erfolgte hexadezimal
0b bzw. 0B
Ausgabe erfolgte binär
0
Ausgabe erfolgte oktal

Gibt bei Gleitkomma-Daten immer den Dezimalpunkt mit aus, unabhängig davon, ob Nachkommastellen vorhanden sind.

1: std::println("*{:#8B}*", 10);
2: std::println("*{:#8x}*", 10);
3: std::println("*{:}*", 12.);
4: std::println("*{:#}*", 12.);

*  0B1010*
*     0xa*
*12*
*12.0*

0: Füllt nicht belegte führende Stellen mit 0 auf, wenn keine Ausrichtung für die Ausgabe definiert ist.

1: std::println("*{:#08B}*", 10);
2: std::println("*{:#08x}*", 10);
3: std::println("*{:#08}*", 12.);

*0B001010*
*0x00000a*
*000012.0*

.precision: Legt bei Gleitkomma-Daten die Anzahl der Nachkommastellen fest. precision ist entweder ein positiver Integer-Wert oder ein weiterer Platzhalter, um die Anzahl der Nachkommastellen dynamisch festzulegen (siehe Zeile 4).

1: auto stellen = 5;
2: std::println("*{}*", 1./3.);
3: std::println("*{:.3}*", 1./3.);
4: std::println("*{:.{}}*", 1./3., stellen);
5: std::println("*{:8.3}*", 1./3.);
6: std::println("*{:08.3}*", 1./3.);

*0.3333333333333333*
*0.333*
*0.33333*
*   0.333*
*0000.333*

Ist das auszugebende Datum ein String, legt precision die Anzahl auszugebenden Zeichen fest.

1: const char* pText = "Dies ist ein String";
2: std::println("*{}*", pText);
3: std::println("*{:.8}*", pText);

*Dies ist ein String*
*Dies ist*

type: Bestimmt wie das auszugebende Datum dargestellt wird.

String-Datum:

type
Darstellung
nichts oder s
Ausgabe als String

Integer-Datum:

type
Darstellung
nichts oder d
Ausgabe als Dezimalzahl
b oder B
Ausgabe als Binärzahl; Präfix 0b oder 0B
c
Ausgabe als Zeichen
o
Ausgabe als Oktalzahl; Präfix 0
x oder X
Ausgabe als Hex-Zahl; Präfix 0x oder 0X
1: std::println("233 = {}",233);
2: std::println("233 = {:#b}",233);
3: std::println("233 = {:#o}",233);
4: std::println("233 = {:#x}",233);

233 = 233
233 = 0b11101001
233 = 0351
233 = 0xe9

Zeichen-Datum:

type
Darstellung
nichts oder c
Ausgabe als Zeichen
b,B,d,o,x,X
Ausgabe als Zahl im entsprechenden Zahlensystem
1: std::println("'A' = {}",'A');
2: std::println("'A' = {:d}",'A');
3: std::println("'A' = {:x}",'A');

'A' = A
'A' = 65
'A' = 41

Gleitkomma-Datum:

type
Darstellung
nichts
Ausgabe als Festkomma oder mit Exponenten
a,A
Ausgabe als Hex-Zahl mit P für den Exponenten
e,E
Ausgabe mit Exponenten
f,F
Ausgabe als Festkomma
g,G
Ausgabe als Festkomma oder mit Exponenten
1: std::println("{:#}, {:#}", 1.E3, 1’000’000.);
2: std::println("{:#a}, {:#A}", 1.E3, 1’000’000.);
3: std::println("{:#e}, {:#E}", 1.E3, 1’000’000.);
4: std::println("{:#f}, {:#F}", 1.E3, 1’000’000.);
5: std::println("{:#g}, {:#G}", 1.E3, 1’000’000.);

1000.0, 1000000.0
0xf.ap+6, 0XF.424P+16
1.000000e+03, 1.000000E+06
1000.000000, 1000000.000000
1000.00, 1.00000E+06

bool-Datum:

type
Darstellung
nichts oder s
Ausgabe als Text true bzw. false
b,B,d,o,x,X
Ausgabe als Integer-Wert
1: bool tVal = true;
2: bool fVal = false;
3: std::println("{}, {:s}", tVal,fVal);
4: std::println("{:d}, {:x}", tVal, fVal);

true, false
1, 0

char-Zeiger:

type
Darstellung
nichts
Ausgabe des Zeigerinhalts oder Textes
p
Ausgabe des Zeigerinhalts in Hex-Darstellung

Anmerkung: Die Ausgabe von Zeigern wird im Kapitel über Zeiger behandelt, da noch die Grundlagen hierzu fehlen.

Escape-Sequenzen

Die Ausgabe von nicht-druckbaren Zeichen, wie z.B. ein Zeilenvorschub oder ein Tabulator, erfolgt durch sogenannte Escape-Sequenzen. Sie können an beliebiger Stelle im auszugebenden Text stehen und beginnen mit einem Backslash-Zeichen \, gefolgt von einem Buchstaben, der die auszuführende 'Aktion' beschreibt.

Die nachfolgende Tabelle enthält eine Übersicht über die wichtigsten Escape-Sequenzen.

Escape-Sequenz
Ausgabe von
\a
Alarmton (Beep)
\b
Backspace
\n
Zeilenvorschub
\r
Return (Zeilenanfang)
\t
horizontaler Tabulator
\\
Backslash (\)
\"
Anführungszeichen
\'
Hochkomma

Die Bedeutung und Wirkungsweise der meisten Escape-Sequenzen dürfte aus deren Beschreibung hervorgehen. Zu beachten ist bei den Escape-Sequenzen \" und \' wann diese notwendig sind. Innerhalb eines Strings ist das Zeichen " als Escape-Sequenz zu definieren, da es standardmäßig diesen begrenzt. Das Zeichen ' benötigt hier keine Escape-Sequenz. Genau andersherum verhält es sich, wenn ein ' als einzelnes Zeichen ausgegeben wird, da ein einzelnes Zeichen in ' eingeschlossen wird.


Copyright 2024 © Wolfgang Schröder
E-Mail mit Fragen oder Kommentaren zu dieser Website an: info@cpp-tutor.de
Impressum & Datenschutz