Formatierte Ein-/Ausgabe mit >>scann()<< und >>printf()<< Flashcards
Welcher include/headerdatei wird für den Befehl
scanf();
benötigt?
<stdio.h>
Wie ist die Signatur von scanf();
int scanf(const char * restrict format, ...);
Was macht die Funktion scanf(); ?
Mit ihr können Werte unterschiedlicher Datentypen formatiert eingelesen werden.
Aus welcher Quelle werden die Daten bei scanf(); eingelesen?
Von der Standarteingabe (stdin)
Was ist normalerweise die Standarteingabe (stdin) ?
Mit Standarteingabe ist normalerweise die Tastatur gemeint.
Kann man die Standarteingabe auch umleiten?
Ja
Was ist ein Beispiel für die Umleitung der Standarteingabe (stdin) ?
Beim Raspberry Pi wird das oft gemacht, wenn dieser ohne Monitor (headless) betrieben wird. Dann wird der z.B. mit einem PC per Telnet oder serieller Schnitstelle verbunden und in stdin erscheinen auf dem Paspberry Pi die Zeichen, die der PC sendet.
Welche Paramter müssen bei scanf(); verwendet werden?
Der erste Paramter ist ein String mit den Formatzeichen der Datentypen, die eingeselen werden sollen. Danach kommen die Speicheradressen der Variablen, in die die eingelesen Werte geschreiben werden sollen. Es können auch nicht Formatzeichen im String angegeben werden. Diese werden bei der Eingabe dann ignoriert.
In welche Einzelteile kann eine Variable zerlegt werden:
- Datentyp
- Name der Variable
- Speicheradresse der Variable
- Wert der Variable
Was macht der &-Operator
Er gibt die Speicheradresse der Variable zurück.
Was ist das Problem mit der Pufferung bei scanf(); ?
Wenn z.B. mit scanf(); ein Char eingelesen werden soll und man die Eingabe mit Enter bestätigt, so bleibt das Enter im Puffer der Standarteingabe und wird in die nächste eingabe geschrieben
Pufferproblem bei scanf - Lösungsvorschlag 1
Die Funktion fflush() um Entleeren des puffers benutzen:
fflush(stdin);
Pufferproblem bei scanf - Lösungsvorschlag 2
Benutzen einer do while-Schleife um das Newline-Zeichen aus dem Puffer zu ziehen:
~~~
do {scanf(“%c”, &a);} while (getchar() != ‘\n’ };
~~~
Pufferproblem bei scanf - Lösungsvorschlag 3
Nicht scanf() verwenden, sondern fgets() zum Einlesen verwenden und sscanf() verwenden um in das entsprechende Format zu konviertieren.
Warum sind scanf() und printf() sicherheitskritische Funktionen
Weil sie nicht gegen eine Buffer Overflow gesichert sind, heißt sie prüfen nicht ob die eingabe vielleicht zu groß ist. Ab C23 sollen sie dejoch gegen Buffer Overflows abgesichert sein.
Wie kann ein Hacker ein Buffer Overflow ausnutzen
Wenn nicht auf Buffer Overflow geprüft wird, können so Daten auserhalb des Buffers überschrieben werden.
Wie kann ich überprüfen ob die Eingaben alle eingelesen wurden.
scanf() gibt die Zahl der erfolgreich eingelesen Werte zurück. Sollte kein Wert erflogreich eingelesen werden wird der Wert 0 zurückgegeben. Wenn ein Wert nicht erfolgreich eingelesen wurde werden die andere auch nicht mehr probiert.
Was passiert wenn bei der Eingabe schon ein Fehler auftrit
Es wird das EOF-Zeichen zurückgegeben.
EOF-Zeichen ist systemabhängig
Wann hört scanf() auf Werte in eine Variable einzulesen?
- bis zum nächsten Whitespace
- bis zu einer bestimmten Feldbreite
- bis zum ersten Zeichen, das nicht merh in ein entsprechndes Format konvertiert werden konnte.
Was ist der Rückgabewert von printf()
Anzahl der Zeichen die ausgegeben werden oder im Fehlerfall EOF.
Begrenzte länge des Formatstrings
Auch mit printf() kann es einen Buffer Overflow geben, sollte der Formatstring länger sein als erlaubt. Nach C99-Standart würde printf() nach 4096 Zeichen Probleme bekommen.
Kann man die Standardausgabe (stdout) auch umleiten?
Ja