C für Dummies. Dan Gookin
Чтение книги онлайн.

Читать онлайн книгу C für Dummies - Dan Gookin страница 35

Название: C für Dummies

Автор: Dan Gookin

Издательство: John Wiley & Sons Limited

Жанр: Программы

Серия:

isbn: 9783527833382

isbn:

СКАЧАТЬ Zum Beweis präsentiere ich das folgende Fragment aus einem Quelltext:

       if (all_else_fails) { display_error(errno); /* Fehlernummer existiert */ walk_away(); } else get_mad();

      Machen Sie sich keine Gedanken über die inhaltliche Bedeutung dieses Codes, das wird Ihnen später klar werden. Achten Sie mal darauf, dass die Funktion display_error einen Kommentar hinter sich stehen hat: Fehlernummer existiert. Aber nehmen wir mal an, Sie wollen mit Ihrem noch kommenden C-Verständnis diesen Teil des Programms auskommentieren, sodass nur noch die get_mad()-Funktion ausgeführt wird. Sie kommentieren also alles andere aus:

       /* if (all_else_fails) { display_error(errno); /* Fehlernummer existiert */ walk_away(); } else */ get_mad();

      So, nun sieht der Compiler nur noch get_mad(), oder?

      Tja, Pustekuchen. Der Kommentar beginnt in der ersten Zeile mit einem /*. Aber er endet in der Zeile mit der display_error-Funktion. Weil die Zeile mit einem */ endet, ist dies auch das Ende des Kommentars. Der C-Compiler macht dann in der Zeile mit der walk_away-Funktion weiter und erzeugt einen Syntaxfehler, sobald er auf die allein stehende geschweifte Klammer } trifft. Das zweite Kommentarende (das über der get_mad()-Funktion) erzeugt auch noch einen Fehler. Zwei Fehler!

      Um diese Falle zu vermeiden, müssen Sie also ein wenig aufpassen, wenn Sie einen Teil des C-Programms ausschalten. Die Lösung hier wäre, Fehlernummer existiert nicht als Kommentar zu schreiben oder Sie kommentieren jede Zeile für sich aus:

       /* display_error(errno); /* Fehlernummer existiert */

      

Außerdem haben Sie vielleicht gemerkt, dass der »neue« Kommentarstil hier auch recht zweckmäßig wäre:

       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.

      СКАЧАТЬ