Die Standardbibliothek <stdio.h> bietet die wichtigsten Funktionen für Text-Ein- und Ausgabe.
Ausgabe
| Funktion | Zweck |
|---|---|
printf(format, ...) | formatierte Ausgabe auf stdout |
puts(text) | Text plus Zeilenumbruch |
putchar(c) | ein Zeichen |
fprintf(stderr, ...) | Fehlerausgabe (getrennt von normaler Ausgabe) |
snprintf(puffer, groesse, format, ...) | formatiert in einen Puffer |
#include <stdio.h>
int main(void) {
puts("Hallo");
putchar('X'); putchar('\n');
fprintf(stderr, "Das geht an stderr\n");
char puffer[50];
int n = snprintf(puffer, sizeof puffer, "%s hat %d Punkte (%.1f%%)", "Mia", 42, 87.5);
printf("%s [%d Zeichen]\n", puffer, n);
return 0;
}Hallo X Mia hat 42 Punkte (87.5%) [25 Zeichen]
Die Ausgabe auf stderr erscheint im Terminal, wird aber getrennt von stdout umgeleitet (./prog > datei.txt).
Eingabe mit scanf
scanf liest formatierte Eingaben von der Tastatur. Übergeben wird die Adresse (&) der Variable:
int alter;
double gewicht;
char name[32];
printf("Name Alter Gewicht: ");
if (scanf("%31s %d %lf", name, &alter, &gewicht) == 3) {
printf("Hallo %s\n", name);
}- Der Rückgabewert ist die Zahl der erfolgreich gelesenen Werte: immer prüfen
- Bei
%sBreite angeben (%31s), sonst droht ein Pufferüberlauf %dint,%lfdouble (beiscanfmitl!),%ffloat,%cZeichen,%sWort bis zum Leerraum- Zeichen, die nicht passen, bleiben im Puffer und blockieren die nächste Eingabe
Sicherer: Zeile lesen, dann auswerten
Das zuverlässigste Muster: erst eine ganze Zeile mit fgets lesen, dann mit sscanf, strtol oder strtod auswerten:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char *eingabe = "Mia 17 62.5\n"; // statt echter Tastatureingabe
char name[32];
int alter;
double gewicht;
if (sscanf(eingabe, "%31s %d %lf", name, &alter, &gewicht) == 3) {
printf("%s, %d Jahre, %.1f kg\n", name, alter, gewicht);
}
char zeile[64] = " 42abc";
char *rest;
long zahl = strtol(zeile, &rest, 10); // Zahl + Rest erkennen
printf("Zahl %ld, Rest \"%s\"\n", zahl, rest);
const char *kaputt = "xyz";
if (sscanf(kaputt, "%d", &alter) != 1) printf("keine Zahl\n");
return 0;
}Mia, 17 Jahre, 62.5 kg Zahl 42, Rest "abc" keine Zahl
Für echte Eingaben: fgets(zeile, sizeof zeile, stdin) liest höchstens sizeof zeile - 1 Zeichen samt Zeilenumbruch, er läuft nie über. Den Zeilenumbruch entfernst du so: zeile[strcspn(zeile, "\n")] = '\0';.
Zeichenweise lesen
int c; // int, nicht char, wegen EOF!
while ((c = getchar()) != EOF) {
putchar(c);
}EOF (Dateiende, bei Tastatur Strg+D bzw. Strg+Z) ist ein int-Wert außerhalb der Zeichen.
Umleitungen in der Shell
./prog < eingabe.txt # stdin aus Datei
./prog > ausgabe.txt # stdout in Datei
./prog 2> fehler.txt # stderr in Datei
./prog | sort | uniq # Ausgabe an anderes ProgrammProgramme, die von stdin lesen und nach stdout schreiben, lassen sich so wie Bausteine kombinieren (UNIX-Philosophie).
Puffer
stdout ist zeilengepuffert (Terminal) oder voll gepuffert (Datei/Pipe). fflush(stdout) erzwingt die Ausgabe sofort, wichtig für Eingabeaufforderungen ohne Zeilenumbruch: printf("Eingabe: "); fflush(stdout);.
Merke
- Ausgabe:
printf,puts,fprintf(stderr, ...); Pufferausgabe mitsnprintf - Eingabe: Zeile mit
fgetslesen, dann mitsscanf/strtol/strtodauswerten - Rückgabewerte von
scanfimmer prüfen; bei%sBreite angeben - Nie
getsbenutzen EOFist einint: Variable mitintdeklarieren
Aufgabe
Lies eine Zeile ein (oder simuliere sie mit einem String), zerlege sie mit sscanf in zwei Zahlen und gib Summe und Produkt aus. Behandle fehlerhafte Eingaben.