In den meisten Ihrer Programme werden Sie Informationen auf dem Bildschirm ausgeben oder Informationen von der Tastatur einlesen müssen. In einem Großteil der bisher vorgestellten Beispielprogramme wurde damit schon gearbeitet, auch wenn Sie vielleicht nicht verstanden haben, wie alles zusammenhängt. Heute lernen Sie:
printf()
und puts()
auf
dem Bildschirm ausgibt
scanf()
von der Tastatur einliest
Die heutige Lektion soll diese Themen nicht vollständig abhandeln, sondern lediglich die grundlegenden Informationen vermitteln, so dass Sie mit dem Schreiben richtiger Programme beginnen können. Etwas weiter hinten in diesem Buch werden wir auf diese Themen noch ausführlicher eingehen.
In den meisten Ihrer Programme werden Sie sicherlich eine Ausgabe auf dem
Bildschirm vorsehen. Und das geschieht am häufigsten über die zwei
Bibliotheksfunktionen von C, printf()
und puts()
.
Die Funktion printf()
ist Teil der C-Standardbibliothek. Sie stellt wahrscheinlich die
flexibelste Option zur Ausgabe von Daten auf den Bildschirm dar. printf()
ist Ihnen
bereits in vielen Beispielen in diesem Buch begegnet. Jetzt sollen Sie erfahren, wie die
Funktion arbeitet.
Die Ausgabe einer Textmeldung auf den Bildschirm ist einfach. Rufen Sie die
Funktion printf()
auf und übergeben Sie ihr die entsprechende Nachricht in
doppelten Anführungszeichen. Um zum Beispiel »Ein Fehler ist aufgetreten!
« auf
den Bildschirm auszugeben, schreiben Sie
printf("Ein Fehler ist aufgetreten!");
Doch meist müssen Sie nicht nur eine Textmeldung, sondern auch den Wert von
Programmvariablen ausgeben. Dies ist etwas komplizierter, als nur eine Meldung
auszugeben. Angenommen Sie wollen zum Beispiel den Wert der numerischen
Variablen x
auf dem Bildschirm zusammen mit erläuterndem Text ausgeben und
dieser Text soll in einer neuen Zeile beginnen. Dazu könnten Sie die printf()
-
Funktion wie folgt verwenden:
printf("\nDer Wert von x ist %d", x);
Unter der Voraussetzung, dass der Wert von x
12
ist, wäre die Ausgabe auf dem
Bildschirm dann:
Der Wert von x ist 12
In diesem Beispiel werden printf()
zwei Argumente übergeben. Das erste Argument
steht in doppelten Anführungszeichen und wird Formatstring genannt. Das zweite
Argument ist der Name der Variablen (x
), die den auszugebenden Wert enthält.
Ein printf()
-Formatstring spezifiziert, wie die Ausgabe zu formatieren ist. Sehen Sie
im Folgenden die drei möglichen Komponenten eines Formatstrings:
D
(in
Der
) bis %
(das nicht dazugehört).
\n
eine Escape-Sequenz. Die Escape-
Sequenz \n
wird als Neue-Zeile-Zeichen bezeichnet und bedeutet: »Begib dich an
den Anfang der nächsten Zeile.« Escape-Sequenzen werden auch dazu genutzt,
um bestimmte Zeichen auszugeben. Die gebräuchlichsten Escape-Sequenzen sind
in Tabelle 6.1 zusammengestellt. Eine vollständige Liste finden Sie in Kapitel 14,
»Zeiger für Fortgeschrittene«.
%
) gefolgt von
einem weiteren Zeichen. Im Beispiel oben lautet der Konvertierungsspezifizierer
%d
. Ein Konvertierungsspezifizierer teilt printf()
mit, wie die auszugebende
Variable zu interpretieren ist. Mit %d
teilen Sie printf()
mit, dass die Variable x
als
Dezimalzahl vom Typ signed
(mit Vorzeichen) zu interpretieren ist.
Escape-Sequenzen dienen dazu, die Position der Ausgabe durch Verschieben des
Cursors auf dem Bildschirm zu steuern. Sie werden aber auch dazu genutzt, um
Zeichen auszugeben, die ansonsten für printf()
eine besondere Bedeutung haben.
Um zum Beispiel einen einfachen Backslash auszugeben, müssen Sie einen doppelten
Backslash (\\
)
in den Formatstring einbauen. Der erste Backslash teilt printf()
mit,
dass der zweite Backslash als literales Zeichen zu verstehen ist und nicht als Beginn
einer Escape-Sequenz. Im Allgemeinen teilen Sie printf()
mit dem Backslash mit,
dass das nächste Zeichen in besonderer Weise zu interpretieren ist. Sehen Sie im
Folgenden einige Beispiele:
Listing 6.1 verwendet einige der gängigsten Escape-Sequenzen.
Listing 6.1: Escape-Sequenzen zusammen mit printf().
1: /* Beispiele für die gängigsten Escape-Sequenzen */
2:
3: #include <stdio.h>
4:
5: #define VERLASSEN 3
6:
7: int menue_option_einlesen( void );
8: void bericht_anzeigen ( void );
9:
10: int main(void)
11: {
12: int option = 0;
13:
14: while (option != VERLASSEN)
15: {
16: option = menue_option_einlesen();
17:
18: if (option == 1)
19: printf("\nAkustisches Signal des Computers\a\a\a" );
20: else
21: {
22: if (option == 2)
23: bericht_anzeigen();
24: }
25: }
26: printf("Sie haben die Option Verlassen gewählt!\n");
27:
28: return 0;
29: }
30:
31: int menue_option_einlesen( void )
32: {
33: int auswahl = 0;
34:
35: do
36: {
37: printf( "\n" );
38: printf( "\n1 - Akustisches Signal des Computers" );
39: printf( "\n2 - Bericht anzeigen");
40: printf( "\n3 - Verlassen");
41: printf( "\n" );
42: printf( "\nGeben Sie Ihre Wahl ein:" );
43:
44: scanf( "%d", &auswahl );
45:
46: }while ( auswahl < 1 || auswahl > 3 );
47:
48: return auswahl;
49: }
50:
51: void bericht_anzeigen( void )
52: {
53: printf( "\nMUSTERBERICHT " );
54: printf( "\n\n Sequenz\tBedeutung" );
55: printf( "\n=========\t=======" );
56: printf( "\n\\a\t\tBeep (Akustisches Signal)" );
57: printf( "\n\\b\t\tBackspace" );
58: printf( "\n...\t\t...");
59: }
1 - Akustisches Signal des Computers
2 - Bericht anzeigen
3 - Verlassen
Geben Sie Ihre Wahl ein:1
Akustisches Signal des Computers
1 - Akustisches Signal des Computers
2 - Bericht anzeigen
3 - Verlassen
Geben Sie Ihre Wahl ein:2
MUSTERBERICHT
Sequenz Bedeutung
========= =======
\a Beep (Akustisches Signal)
\b Backspace
... ...
1 - Akustisches Signal des Computers
2 - Bericht anzeigen
3 - Verlassen
Geben Sie Ihre Wahl ein:3
Sie haben die Option Verlassen gewählt!
Listing 6.1 scheint im Vergleich zu den bisherigen Beispielen ziemlich lang und es
enthält einige Zusätze, die man genauer untersuchen sollte. Die Header-Datei stdio.h
wird in Zeile 3 eingebunden, da in diesem Listing printf()
verwendet wird. Zeile 5
definiert eine Konstante namens VERLASSEN
. Vom Abschnitt »Daten speichern:
Variablen und Konstanten« aus Tag 2 wissen Sie vielleicht noch, dass Sie mit #define
die Konstante VERLASSEN
gleichsetzen mit dem Wert 3
. Die Zeilen 7 und 8 enthalten
Funktionsprototypen. Dieses Programm verwendet zwei Funktionen:
menue_option_einlesen()
und bericht_anzeigen()
. Die Funktion
menue_option_einlesen()
wird in den Zeilen 31 bis 49 definiert. Sie hat Ähnlichkeit
mit der Menü-Funktion aus Listing 5.5. Die Zeilen 37 und 41 enthalten Aufrufe von
printf()
, in denen die Escape-Sequenz Neue Zeile
ausgegeben wird. Die Zeilen 38,
39, 40 und 42 enthalten neben dem Neue-Zeile-Escape-Zeichen noch Text zum
Ausgeben. Zeile 37 könnte man fortlassen, wenn man Zeile 38 wie folgt ändern
würde:
printf( "\n\n1 - Akustisches Signal des Computers" );
Mit der zusätzlichen Zeile 37 ist das Programm jedoch leichter zu lesen.
Werfen wir einen Blick auf die Funktion main()
. In Zeile 14 beginnt eine while
-
Schleife, deren Anweisungen so lange durchlaufen werden, wie option
ungleich
VERLASSEN
ist. Da VERLASSEN
eine Konstante ist, hätten Sie sie auch durch 3
ersetzen
können. Dann wäre das Programm jedoch nicht so klar. Zeile 16 weist den Code der
vom Anwender getroffenen Auswahl der Variablen option
zu, die dann in den Zeilen
18 bis 25 in einer if
-Anweisung analysiert wird. Wenn der Anwender 1
wählt, gibt
Zeile 19 das Neue-Zeile-Zeichen, eine Meldung und drei Warntöne aus. Und wenn der
Anwender 2
wählt, ruft Zeile 23 die Funktion bericht_anzeigen()
auf.
Die Funktion bericht_anzeigen()
ist in den Zeilen 51 bis 59 definiert. Diese einfache
Funktion zeigt, wie einfach es ist, mit printf()
und den Escape-Sequenzen
formatierte Informationen auf dem Bildschirm auszugeben. Das Neue-Zeile-Zeichen
haben Sie bereits kennen gelernt. In den Zeilen 54 bis 58 finden Sie darüber hinaus
das Escape-Zeichen für den Tabulator: \t
. Das Tabulatorzeichen richtet die Spalten
des Berichts vertikal aus. Die Zeilen 56 und 57 mögen auf den ersten Blick etwas
verwirren, doch wenn Sie sie von links nach rechts durchgehen, dürften sie den Sinn
schnell erkennen. Zeile 56 gibt eine neue Zeile aus (\n
), danach einen Backslash (\
)
gefolgt von dem Buchstaben a
und anschließend zwei Tabulatoren (\t\t
). Die Zeile
endet mit einem beschreibenden Text (Beep (Akustisches Signal)
). Zeile 57 folgt
dem gleichen Muster.
Dieses Programm gibt die ersten zwei Zeilen der Tabelle 6.1 zusammen mit einem Titel für den Bericht und Spaltenüberschriften aus. In Übung 9 am Ende dieser Lektion sollen Sie dieses Programm vervollständigen, so dass es den Rest der Tabelle ausgibt.
Der Formatstring muss für jede ausgegebene Variable einen
Konvertierungsspezifizierer enthalten. Die Funktion printf()
gibt jede Variable so
aus, wie es durch den entsprechenden Konvertierungsspezifizierer vorgegeben ist.
Mehr dazu erfahren Sie am Tag 15, »Mit Dateien arbeiten«. Im Moment reicht es,
wenn Sie sich vergewissern, dass Sie stets den Konvertierungsspezifizierer verwenden,
der mit dem Typ der auszugebenden Variablen übereinstimmt.
Was genau ist damit gemeint? Wenn Sie eine vorzeichenbehaftete Dezimalzahl (Typ
int
oder long
) ausgeben wollen, verwenden Sie den Konvertierungsspezifizierer %d
.
Für vorzeichenlose Dezimalzahlen (Typ unsigned int
oder unsigned long
) verwendet
man %u
und für Fließkomma-Variablen (Typ float
oder double
) den Spezifizierer %f
.
Die am häufigsten verwendeten Konvertierungsspezifizierer sind in Tabelle 6.2
zusammengefasst
Alle Programme, die
printf()
verwenden,
sollten die Header-Dateistdio.h
einbinden.
Der literale Text eines Formatspezifizierers ist alles, was weder Escape-Sequenz noch Konvertierungsspezifizierer ist. Literaler Text wird genauso ausgegeben, wie er da steht, einschließlich aller Leerzeichen.
Kann man auch Werte von mehreren Variablen ausgeben? Eine einzige printf()
-
Anweisung kann eine unbegrenzte Anzahl von Variablen ausgeben, aber der
Formatstring muss für jede Variable einen Konvertierungsspezifizierer enthalten. Die
Konvertierungsspezifizierer sind mit den Variablen paarweise verbunden und werden
von links nach rechts gelesen. Wenn Sie also schreiben
printf("Rate = %f, Betrag = %d", rate, betrag);
bildet die Variable rate
ein Paar mit dem Spezifizierer %f
und die Variable betrag
mit
dem Spezifizierer %d
. Die Positionen der Konvertierungsspezifizierers im Formatstring
legen die Position der Ausgabe fest. Wenn printf()
mehr Variablen übergeben
werden, als es Konvertierungsspezifizierer gibt, werden die überflüssigen Variablen
nicht ausgegeben. Gibt es hingegen mehr Spezifizierer als Variablen, geben die
unbenutzten Spezifizierer »Müll« aus.
Sie können mit printf()
nicht nur die Werte von Variablen ausgeben. Jeder gültige
C-Ausdruck kann als Argument dienen. Um zum Beispiel die Summe von x
und y
auszugeben, könnten Sie schreiben
z = x + y;
printf("%d", z);
Sie könnten aber auch schreiben
printf("%d", x + y);
Listing 6.2 veranschaulicht Ihnen die Verwendung von printf()
. Am Tag 15 erhalten
Sie ausführlichere Informationen zu dieser Funktion.
Listing 6.2: Mit printf() numerische Werte ausgeben.
1: /* Beispiel, das mit printf() numerische Werte ausgibt. */
2:
3: #include <stdio.h>
4:
5: int a = 2, b = 10, c = 50;
6: float f = 1.05, g = 25.5, h = -0.1;
7:
8: int main(void)
9: {
10: printf("\nDezimalwerte ohne Tabulatoren: %d %d %d", a, b, c);
11: printf("\nDezimalwerte mit Tabulatoren: \t%d \t%d \t%d", a, b, c);
12:
13: printf("\nDrei Fliesskommazahlen in einer Zeile: \t%f\t%f\t%f",f,g,h);
14: printf("\nDrei Fliesskommazahlen in drei Zeilen: \n\t%f\n\t%f\n\t%f",
15: f,g,h);
16: printf("\nDie Quote beträgt %f%%", f);
17: printf("\nDas Ergebnis von %f/%f = %f\n", g, f, g / f);
18:
19: return 0;
20: }
Dezimalwerte ohne Tabulatoren: 2 10 50
Dezimalwerte mit Tabulatoren: 2 10 50
Drei Fliesskommazahlen in einer Zeile: 1.050000 25.500000 -0.100000
Drei Fliesskommazahlen in drei Zeilen:
1.050000
25.500000
-0.100000
Die Quote beträgt 1.050000%
Das Ergebnis von 25.500000/1.050000 = 24.285715
Listing 6.2 gibt neun Zeilen aus. Die Zeilen 10 und 11 geben jeweils drei
Dezimalzahlen aus: a
, b
und c
. In Zeile 10 stehen diese Zahlen ohne Tabulator einfach
hintereinander, in Zeile 11 sind sie durch Tabulatoren getrennt. Die Zeile 13 und 14
geben jeweils drei Variablen vom Typ float
aus: f
, g
und h
. In Zeile 13 werden sie in
einer Zeile und in Zeile 14 in drei Zeilen ausgegeben. Zeile 16 gibt eine
Fließkommazahl, f
, gefolgt von einem Prozentzeichen aus. Da ein Prozentzeichen in
der Regel darauf hinweist, dass eine Variable auszugeben ist, müssen Sie zwei
Prozentzeichen hintereinander setzen, um ein einfaches Prozentzeichen anzuzeigen.
Dies entspricht der Vorgehensweise wie beim Backslash-Escape-Zeichen. Zeile 17
schließlich veranschaulicht die Ausgabe von Ausdrücken - wie zum Beispiel g/f
.
#include <stdio.h>
printf( Formatstring[,Argumente,...]);
printf()
ist eine Funktion, die einen Formatstring mit Konvertierungsspezifizierern
und für jeden Konvertierungsspezifizierer ein zugehöriges Argument
übernimmt. Die
Funktion gibt die formatierten Informationen auf dem Standardausgabegerät,
normalerweise dem Bildschirm, aus. Bei Verwendung von printf()
müssen Sie die
Header-Datei für die Standardein-/-ausgabe, stdio.h
, einbinden.
Der Formatstring
ist obligatorisch, die Argumente
hingegen sind optional. Zu jedem
Argument muss es einen Konvertierungsspezifizierer geben. Die gebräuchlichsten
Konvertierungsspezifizierer finden Sie in Tabelle 6.2.
Der Formatstring
kann außerdem Escape-Sequenzen enthalten. In Tabelle 6.1 sind
die am häufigsten verwendeten Escape-Sequenzen aufgeführt.
Sehen Sie im Folgenden einige Beispiele für printf()
-Aufrufe und die dazugehörige
Ausgabe:
#include <stdio.h>
int main(void)
{
printf("Dies ist ein Beispiel für eine Ausgabe!\n");
return 0;
}
Dies ist ein Beispiel für eine Ausgabe!
printf ("Dieser Befehl gibt ein Zeichen, %c\neine Zahl,
%d\nund eine Fließkommazahl, %f\naus ", 'z', 123, 456.789);
Dieser Befehl gibt ein Zeichen, z
eine Zahl, 123
und eine Fließkommazahl, 456.789
aus
Um Text auf dem Bildschirm anzuzeigen, kann auch die Funktion puts()
verwendet
werden. Sie erlaubt allerdings nicht die Ausgabe numerischer Variablen. Die Funktion
puts()
übernimmt einen einfachen String als Argument und gibt diesen aus, wobei am
Ende automatisch eine neue Zeile begonnen wird. Die Anweisung
puts("Hallo, Welt.");
hat daher den gleichen Effekt wie
printf("Hallo, Welt.\n");
Sie können in dem String, der puts()
übergeben wird, auch Escape-Sequenzen
(einschließlich \n
) verwenden. Sie bewirken das Gleiche wie bei der Funktion printf()
(Tabelle 6.1 listet die gebräuchlichsten Escape-Sequenzen auf).
Wie bei printf()
muss in jedem Programm, das puts()
verwendet, die Header-Datei
stdio.h
mit angegeben werden (falls nicht schon geschehen).
#include <stdio.h>
puts( string );
puts()
ist eine Funktion, die einen String auf dem Standardausgabegerät,
normalerweise dem Bildschirm, ausgibt. Wenn Sie puts()
verwenden, müssen Sie die
Header-Datei stdio.h
für die Standarein-/-ausgabe einbinden. puts()
hängt
automatisch ein Neues-Zeile-Zeichen an das Ende des auszugebenden Strings an. Der
Formatstring darf Escape-Sequenzen enthalten. Die gängigsten Escape-Sequenzen
finden Sie in Tabelle 6.1.
Sehen Sie im Folgenden einige Beispiele für puts()
-Aufrufe und die dazugehörige
Ausgabe:
puts("Dieser Text wird mit der puts()-Funktion ausgegeben!");
Dieser Text wird mit der puts()-Funktion ausgegeben!
puts("Diese Ausgabe steht in der ersten Zeile.\nDiese in der zweiten.");
puts("Diese Ausgabe erfolgt in der dritten Zeile.");
puts("Mit printf() würden die vier Zeilen in zwei Zeilen stehen!");
Diese Ausgabe steht in der ersten Zeile.
Diese in der zweiten.
Diese Ausgabe erfolgt in der dritten Zeile.
Mit printf() würden die vier Zeilen in zwei Zeilen stehen!
Ebenso häufig, wie Programme Daten auf dem Bildschirm ausgeben müssen, sind sie
gezwungen, Daten von der Tastatur einzulesen. Am flexibelsten ist dabei die
Bibliotheksfunktion scanf()
.
Die Funktion scanf()
liest Daten, die einem vorgegebenen Format entsprechen, von
der Tastatur ein und weist diese einer oder mehreren Programmvariablen zu. Wie
schon printf()
verwendet auch scanf()
einen Formatstring, um das Format der
Eingabe festzulegen. Dabei kommen im Formatstring die gleichen
Konvertierungsspezifizierer wie bei printf()
zur Anwendung. So liest zum Beispiel die
Anweisung
scanf("%d", &x);
eine Dezimalzahl von der Tastatur ein und weist sie der Integer-Variablen x
zu.
Entsprechend liest die folgende Anweisung eine Fließkommazahl von der Tastatur ein
und weist sie dann der Variablen rate
zu:
scanf("%f", &rate);
Was jedoch hat das kaufmännische Und (&
) vor dem Variablennamen zu suchen? Das
&
-Symbol ist der Adressoperator von C, der am Tag 8, »Zeiger«, noch ausführlich
beschrieben wird. Momentan reicht es, sich zu merken, dass in der Argumentenliste
von scanf()
vor jedem numerischen Variablennamen das Symbol &
gesetzt werden
muss (es sei denn die Variable ist ein Zeiger, was ebenfalls erst am Tag 8 erläutert
wird).
Mit einer einzigen scanf()
-Funktion können Sie mehrere Werte einlesen.
Voraussetzung ist jedoch, dass Sie mehrere Konvertierungsspezifizierer im
Formatstring und mehrere Variablennamen (jeweils mit vorangestelltem &
-Zeichen) in
der Argumentenliste angeben. Die folgende Anweisung nimmt einen Integer- und
einen Fließkommawert auf und weist sie den Variablen x
beziehungsweise rate
zu:
scanf("%d %f", &x, &rate);
Wenn mehrere Variablen eingegeben werden, verwendet scanf()
Whitespace-
Zeichen, um die Eingabe in Felder zu unterteilen. Zu den Whitespace-Zeichen
gehören Leerzeichen, Tabulatoren oder Neue-Zeilen-Zeichen. Jeder
Konvertierungsspezifizierer in dem scanf()
-Formatstring wird mit einem Eingabefeld
abgeglichen. Das Ende eines Eingabefeldes wird durch ein Whitespace-Zeichen
markiert.
Dadurch sind Sie ziemlich flexibel. Eine Eingabe für den obigen scanf()
-Aufruf könnte
beispielsweise wie folgt aussehen:
10 12.45
Oder Sie könnten die Werte so eingeben:
10 12.45
10
12.45
Solange ein Whitespace-Zeichen zwischen den Werten steht, kann scanf()
jeden
Wert seiner Variablen zuweisen.
Wie schon bei den anderen heute vorgestellten Funktionen müssen Programme, die
scanf()
verwenden, die Header-Datei stdio.h
einbinden. Listing 6.3 zeigt ein Beispiel
für den Einsatz von scanf()
(siehe dazu auch das Kapitel zu Tag 15).
Listing 6.3: Numerische Werte mit scanf() einlesen.
1: /* Beispiel für die Verwendung von scanf() */
2:
3: #include <stdio.h>
4:
5: #define VERLASSEN 4
6:
7: int menue_option_einlesen( void );
8:
9: int main(void)
10: {
11: int option = 0;
12: int int_var = 0;
13: float float_var = 0.0;
14: unsigned unsigned_var = 0;
15:
16: while (option != VERLASSEN)
17: {
18: option = menue_option_einlesen();
19:
20: if (option == 1)
21: {
22: puts("\nGeben Sie eine vorzeichenbehaftete Dezimalzahl ein \
(z.B. -123)");
23: scanf("%d", &int_var);
24: }
25: if (option == 2)
26: {
27: puts("\nGeben Sie eine Fliesskommazahl ein (z.B. 1.23)");
28:
29: scanf("%f", &float_var);
30: }
31: if (option == 3)
32: {
33: puts("\nGeben Sie eine vorzeichenlose Dezimalzahl ein \
34: (z.B. 123)" );
35: scanf( "%u", &unsigned_var );
36: }
37: }
38: printf("\nIhre Werte lauten: int: %d float: %f unsigned: %u \n",
39: int_var, float_var, unsigned_var );
40:
41: return 0;
42: }
43:
44: int menue_option_einlesen( void )
45: {
46: int auswahl = 0;
47:
48: do
49: {
50: puts( "\n1 - Eine vorzeichenbehaftete Dezimalzahl einlesen" );
51: puts( "2 - Eine Fliesskommazahl einlesen" );
52: puts( "3 - Eine vorzeichenlose Dezimalzahl einlesen" );
53: puts( "4 - Verlassen" );
54: puts( "\nTreffen Sie eine Wahl:" );
55:
56: scanf( "%d", &auswahl );
57:
58: }while ( auswahl < 1 || auswahl > 4 );
59:
60: return auswahl;
61: }
1 - Eine vorzeichenbehaftete Dezimalzahl einlesen
2 - Eine Fliesskommazahl einlesen
3 - Eine vorzeichenlose Dezimalzahl einlesen
4 - Verlassen
Treffen Sie eine Wahl:
1
Geben Sie eine vorzeichenbehaftete Dezimalzahl ein (z.B. -123)
-123
1 - Eine vorzeichenbehaftete Dezimalzahl einlesen
2 - Eine Fliesskommazahl einlesen
3 - Eine vorzeichenlose Dezimalzahl einlesen
4 - Verlassen
Treffen Sie eine Wahl:
3
Geben Sie eine vorzeichenlose Dezimalzahl ein (z.B. 123)
321
1 - Eine vorzeichenbehaftete Dezimalzahl einlesen
2 - Eine Fliesskommazahl einlesen
3 - Eine vorzeichenlose Dezimalzahl einlesen
4 - Verlassen
Treffen Sie eine Wahl:
2
Geben Sie eine Fliesskommazahl ein (z.B. 1.23)
1231.123
1 - Eine vorzeichenbehaftete Dezimalzahl einlesen
2 - Eine Fliesskommazahl einlesen
3 - Eine vorzeichenlose Dezimalzahl einlesen
4 - Verlassen
Treffen Sie eine Wahl:
4
Ihre Werte lauten: int: -123 float: 1231.123047 unsigned: 321
Listing 6.3 verwendet das gleiche Menükonzept wie Listing 6.1. Die Unterschiede in
menue_option_einlesen()
(Zeilen 44 bis 61) sind zwar geringfügiger Art, sollten aber
dennoch nicht unberücksichtigt bleiben. Zum einen wird anstelle von printf()
die
Funktion puts()
verwendet. Da keine Variablen ausgegeben werden, besteht keine
Notwendigkeit für printf()
. Durch das Einsetzen von puts()
wiederum wurden in den
Zeilen 51 bis 53 die Neue-Zeile-Zeichen entfernt. Zeile 58 hat ebenfalls eine
Änderung erfahren und erlaubt die Eingabe von Werten zwischen 1 und 4, da jetzt
unter vier Menüoptionen gewählt werden kann. Beachten Sie, dass Zeile 56 nicht
geändert wurde, jetzt aber vielleicht etwas mehr Sinn ergibt. scanf()
liest einen
Dezimalwert ein und legt ihn in der Variablen auswahl
ab. Die Funktion liefert in Zeile
60 den Wert von auswahl
zurück an das aufrufende Programm.
Die Listings 6.1 und 6.3 weisen die gleiche main()
-Struktur auf. Eine if
-Anweisung
wertet option
aus, den Rückgabewert von menue_option_einlesen()
. In Abhängigkeit
vom Wert in der Variablen option
gibt das Programm eine Meldung aus, bittet um die
Eingabe einer Zahl und liest den Wert mittels scanf()
ein. Beachten Sie den
Unterschied zwischen den Zeilen 23, 29 und 35. Jede dieser Zeilen liest eine Variable
ein, aber jede Zeile erwartet einen anderen Variablentyp. In den Zeilen 12 bis 14
werden die Variablen der entsprechenden Typen deklariert.
Wenn der Anwender die Menüoption zum Verlassen auswählt, gibt das Programm für
alle drei Variablentypen die jeweils zuletzt eingegebene Zahl aus. Wenn der Anwender
keinen Wert eingegeben hat, wird jeweils 0
ausgegeben, da in den Zeilen 12, 13 und
14 alle drei Typen mit 0
initialisiert wurden. Noch eine letzte Bemerkung zu den
Zeilen 20 bis 36. Die hier verwendeten if
-Anweisungen sind nicht besonders gut
strukturiert. Sollten Sie der Meinung sein, dass eine if...else
-Struktur hier besser
angebracht wäre, möchte ich Ihnen nicht widersprechen. Am Tag 13, »Mit Bildschirm
und Tastatur arbeiten«, werde ich Ihnen switch
- eine weitere Anweisung zur
Programmfluss-Steuerung - vorstellen. Diese Anweisung bietet sogar eine noch
bessere Lösung.
#include <stdio.h>
scanf( Formatstring[,Argumente,...]);
scanf()
ist eine Funktion, die Konvertierungsspezifizierer in einem gegebenen
Formatstring verwenden, um Werte in Variablen-Argumenten einzulesen. Als
Argumente müssen die Adressen der Variablen und nicht die Variablen selbst
übergeben werden. Im Falle von numerischen Variablen können Sie die Adresse
übergeben, indem Sie den Adressoperator (&
) vor den Variablennamen setzen. Die
Verwendung von scanf()
bedarf der Einbindung der Header-Datei stdio.h
.
scanf()
liest die Eingabefelder aus dem Standard-Eingabestrom, normalerweise die
Tastatur. Sie legt jedes dieser eingelesenen Felder in einem Argument ab. Beim
Ablegen der Informationen konvertiert die Funktion die Daten in das Format des
zugehörigen Spezifizierers des Formatstrings. Zu jedem Argument muss ein
Konvertierungsspezifizierer angegeben werden. Tabelle 6.2 enthält die gängigsten
Konver-tierungsspezifizierer.
int x, y, z;
scanf( "%d %d %d", &x, &y, &z);
#include <stdio.h>
int main(void)
{
float y;
int x;
puts( "Geben Sie eine Fliesskommazahl ein und dann einen Integer" );
scanf( "%f %d", &y, &x);
printf( "\nIhre Eingabe lautete %f und %d ", y, x );
return 0;
}
Mit der Beendigung der heutigen Lektion haben Sie das Rüstzeug, um Ihre eigenen
C-Programme zu schreiben. Durch die Kombination der Funktionen printf()
, puts()
und scanf()
und der Anweisungen zur Programmsteuerung, die bereits besprochen
wurden, ist es Ihnen möglich, einfache Programme zu schreiben.
Für die Anzeige auf dem Bildschirm stehen Ihnen die Funktionen printf()
und puts()
zur Verfügung. puts()
kann nur Text ausgeben, während printf()
sowohl Text als
auch Variablen ausgeben kann. Beide Funktionen verwenden Escape-Sequenzen zur
Ausgabe von Steuerzeichen und Sonderzeichen.
Die Funktion scanf()
liest einen oder mehrere Werte von der Tastatur ein und
interpretiert sie gemäß den verwendeten Konvertierungsspezifizierern. Die
eingelesenen Werte werden Programmvariablen zugewiesen.
Frage:
Warum sollte ich puts()
verwenden, wenn printf()
den gleichen
beziehungsweise einen größeren Leistungsumfang als puts()
hat?
Antwort:
Da printf()
mehr kann, weist es auch mehr Overhead auf. Wenn Sie
versuchen, ein kleines effizientes Programm zu schreiben, oder wenn Ihre
Programme sehr groß und die Ressourcen immer wichtiger werden, nutzen
Sie den geringen Overhead von puts()
. Allgemein gilt, dass Sie möglichst
ressourcen-schonend programmieren sollten.
Frage:
Warum muss ich stdio.h
einbinden, wenn ich printf()
, puts()
oder scanf()
verwende?
Antwort:
stdio.h
enthält die Prototypen für die Standardein-/-ausgabefunktionen.
printf()
, puts()
und scanf()
sind drei dieser Standardfunktionen. Versuchen
Sie einmal, ein Programm ohne die Header-Datei stdio.h
auszuführen, und
schauen Sie sich die Fehlermeldungen und Warnungen an, die Sie
unweigerlich erhalten.
Frage:
Was passiert, wenn ich den Adressoperator (&
) bei einer scanf()
-Variablen
vergesse?
Antwort:
Dieser Fehler kann sehr leicht passieren. Und unvorhersehbar sind die
Ergebnisse. Wenn Sie Kapitel 9 und 13 gelesen haben und mehr über Zeiger
wissen, werden Sie das besser verstehen. Im Moment reicht es, zu wissen, dass
scanf()
beim Fortlassen des Adressoperators die eingegebenen Informationen
nicht in Ihrer Variablen, sondern an einer anderen Stelle im Speicher ablegt.
Die Folgen reichen von »scheinbar ohne Auswirkungen« bis
»Programmabsturz mit Fehlermeldung«. Zum Glück können Sie den gcc
jedoch so einstellen, dass alle Warnungen angezeigt werden. Dann wird Ihnen
mitgeteilt, wenn Sie vergessen haben, den Adressoperator zusammen mit
einem Aufruf an scanf()
zu verwenden.
Der Workshop enthält Quizfragen, die Ihnen helfen sollen, Ihr Wissen zu festigen, sowie Übungen, die Sie anregen sollen, das Gelernte umzusetzen und eigene Erfahrungen zu sammeln. Die Lösungen zu den Fragen und den Übungen finden Sie in Anhang C.
puts()
und printf()
?
printf()
einbinden
müssen?
\\
\b
\n
\t
\a
puts()
?
b
\b
\
\\
Ab heute werden Sie mit Übungen konfrontiert, in denen Sie vollständige Programme zur Lösung bestimmter Aufgaben schreiben sollen. Da es jedoch immer mehr als eine Lösung in C gibt, sollten die Antworten am Ende des Buches nicht als die einzig korrekten betrachtet werden. Wenn Sie eigenen Code aufsetzen, der genau das macht, was gefordert war, umso besser! Wenn Sie Probleme haben, finden Sie vielleicht Hilfe in der Antwort. Die Antworten weisen nur wenige Kommentare auf, da es eine gute Übung ist, das Programm selbst nachzuvollziehen.
printf()
- und eine puts()
-Anweisung auf, die eine neue Zeile
beginnen.
scanf()
-Anweisung auf, die ein Zeichen, eine vorzeichenlose
Dezimalzahl und ein weiteres einfaches Zeichen einliest.
2
,4
,6
und so
weiter) akzeptiert werden.
printf( "Jack sagte, "Fischers Fritze fischt frische Fische."");
int hole_1_oder_2( void )
{
int antwort = 0;
while (antwort < 1 || antwort > 2)
{
printf(1 für Ja, 2 für Nein eingeben);
scanf( "%f", antwort );
}
return antwort;
}
bericht_anzeigen()
aus Listing 6.1 so, dass der Rest
der Tabelle 6.1 ausgegeben wird.