C für Dummies. Dan Gookin. Читать онлайн. Newlib. NEWLIB.NET

Автор: Dan Gookin
Издательство: John Wiley & Sons Limited
Серия:
Жанр произведения: Программы
Год издания: 0
isbn: 9783527833382
Скачать книгу
display_error(errno); // Fehlernummer existiert

      Denn Kommentare mit /* und */ beziehungsweise mit // ignorieren sich gegenseitig.

image

      Abbildung 3.2: Die Tücken verschachtelter Kommentare

      Verschachtelte Kommentare sind nervig, aber Sie müssen sich jetzt noch keine Gedanken darüber machen.

      Die printf- und die scanf-Funktion sind natürlich nicht der einzige Weg, um Text aus- oder einzugeben. Dreimal Nein. Die Sprache C ist voll mit Tricks, um dieses Ziel zu erreichen. Und wenn Sie herausfinden, wie begrenzt und lahm diese sind, dann werden Sie Ihre eigenen Funktionen zum Lesen von Tastatureingaben und zur Ausgabe von Informationen schreiben wollen. Aber bis dahin müssen Sie mit den Bordmitteln leben.

       Und tschüss scanf, willkommen fgets

      fgets ist nett und einfach. scanf ist im Vergleich dazu undurchsichtig. Dennoch machen beide Ähnliches: Zeichen von der Tastatur einlesen und in einer Variablen speichern. fgets liest allerdings nur Text ein, scanf kann auch numerische Werte und verschiedene Stringarten einlesen.

      Das Format von fgets können Sie im Kasten »Die Funktion fgets« sehen.

       Ein unfreundliches Programmbeispiel

      Es folgt nun das Programm Insult1.c. Das Programm ist praktisch identisch mit dem Programm Whoru.c.

       #include <stdio.h> int main() { char idiot[21]; printf("Name eines Idioten: "); scanf("%s", idiot); printf("Yep, ich denke auch, dass %s ein Idiot ist.\n", idiot); return 0; }

      Listing 3.7: Name: Insult1.c

      Geben Sie Insult1.c in Ihrem Editor ein, kompilieren und starten Sie das Programm. Bei Fehlern vergleichen Sie die genaue Schreibweise, Anführungszeichen und Semikolons.

      Die Ausgabe sieht dann so aus:

       Name eines Idioten: Karl Klammer Yep, ich denke auch, dass Karl Klammer ein Idiot ist.

      Mit scanf wird die Eingabe gelesen. Egal, was eingelesen wird, die printf-Anweisung kann es ausgeben.

       Das finstere Geheimnis der Sprache C

      Eine dramatische Überschrift – aber was hat scanf damit zu tun? Sicherlich haben Sie schon oft in Artikeln von Speicherüberläufen oder sogenannten Buffer-Overflows gehört.

      Bei mir stürzt dann das Programm ab.

      

Sollte sich der Effekt bei Ihnen nicht gleich einstellen, tippen Sie einfach einen noch längeren Namen ein. Wann es genau passiert, ist vom Betriebssystem und vom Compiler abhängig.

      Was ist passiert? Erinnern Sie sich: Mit idiot[21] haben wir Speicher für 20 Zeichen (und Nullbyte) reserviert. Und nun füttern Sie aber scanf mit viel mehr Zeichen. Wohin soll er das alles packen? Und genau das ist das Problem. scanf bekommt den Hals nicht voll genug, und liest immer weiter Zeichen ein. Diese werden einfach immer weiter in den Speicher geschrieben, bis irgendwann etwas kaputtgeht – der Programmabsturz ist unausweichlich.

      Das klingt zwar harmlos, ist aber eine der großen Sicherheitslücken im Zeitalter des Internets geworden und hat auch den Ruf der Sprache C erheblich beschädigt, denn C ist sehr anfällig dafür.

      

Durch clevere Eingaben gelingt es Hackern hiermit sogar, Maschinencode in den Speicher zu schmuggeln, der dann ausgeführt wird. Auf diese Weise kann man den Computer fernsteuern oder eigene Programme starten.

       Sichere Dateneingaben

      Was jetzt? Müssen wir deshalb aufhören, die Sprache C zu benutzen? Nein, Sie müssen einfach nur damit aufhören, Funktionen wie scanf zu verwenden. Es gibt eine sichere Alternative dazu: den großen Bruder fgets. Da ist auch das f wieder. Schauen Sie sich zunächst das Programm InsultSicher.c an.

       #include <stdio.h> int main() { char idiot[20]; printf("Name eines Idioten: "); fgets(idiot, 20, stdin); printf("Yep, ich denke auch, dass %s ein Idiot ist.\n", idiot); return 0; }

      Listing 3.8: Name: InsultSicher.c

      Es fällt sofort auf, dass fgets als zweiten Parameter die Zahl 20 verwendet. Die kennen wir schon – es ist die Maximallänge von unserem String idiot mitsamt diesem famosen Nullbyte. Damit verhindert fgets, dass mehr Zeichen eingelesen werden können, als Platz vorhanden ist, und Speicherüberläufe wie bei scanf sind damit ausgeschlossen.

      Die Funktion fgets liest über die Tastatur eingegebene Zeichen ein und speichert diese in einer Stringvariablen, die bereits zuvor über das Schlüsselwort char erzeugt worden sein muss. Die Funktion hört mit dem Lesen von Zeichen auf, sobald die

-Taste gedrückt wird. Es werden nur maximal length Zeichen in den String gelesen. War der String kürzer als length und wurde die
-Taste gedrückt, so ist das Zeichen \n ebenfalls im String enthalten.

      Der String wird von einem Nullbyte beendet.

       fgets(var, length, stdin);

      fgets folgt ein Paar runde Klammern, dahinter ein Semikolon, dazwischen der Name einer Stringvariablen, die Anzahl der Zeichen, die Sie lesen wollen – und eine Variable mit dem Namen stdin.

      stdin heißt Standard Input und bezeichnet den Zeichenstrom, der von der Tastatur in das Programm fließt (sehr poetisch).

      Die fgets-Funktion ist eine vollständige Anweisung in C. Sie endet daher auch immer mit einem Semikolon.

       Скачать книгу