Input e output in C
In questa pagina 6
Tutto l'I/O standard è in <stdio.h>. I flussi predefiniti sono stdin, stdout, stderr (vedi Input e output da consoleinput() restituisce sempre una stringa da convertire; lettura di più valori su una riga; print con sep, end e file; flussi standard stdin, stdout, stderr e reindirizzamento.Input e output da console → per il caso Python).
printf
printf("%d %5d %-5d|\n", 42, 42, 42); /* "42 42 42 |" */
printf("%.2f %8.3f\n", 3.14159, 2.5); /* "3.14 2.500" */
printf("%c %s\n", 'A', "testo");
printf("%e\n", 12345.678); /* 1.234568e+04 */Forma generale %[flag][larghezza][.precisione]tipo: - allinea a sinistra, 0 riempie con zeri. Specificatori principali in Dal Python al CStruttura di un programma C, compilazione con gcc (preprocessore, compilatore, linker), main e valore di ritorno, dichiarazioni con tipo statico, printf di base; corrispondenze con Python.Dal Python al C →.
scanf
int n;
double x;
char nome[32];
scanf("%d", &n); /* serve l'INDIRIZZO della variabile */
scanf("%lf", &x); /* %lf per double in scanf (in printf basta %f) */
scanf("%31s", nome); /* un array è già un indirizzo: niente & */scanfsalta gli spazi bianchi prima di%d,%lf,%s(non prima di%c: per saltarli si scrive" %c").%slegge una parola (si ferma al primo spazio); la larghezza (%31s) evita di scrivere oltre l'array, lasciando posto a'\0'.- Valore di ritorno: numero di valori letti con successo, oppure
EOFa fine input. Va controllato:
int a, b;
if (scanf("%d %d", &a, &b) != 2) {
fprintf(stderr, "input non valido\n");
return 1;
}
/* somma di interi fino a fine input */
int x, somma = 0;
while (scanf("%d", &x) == 1)
somma += x;Se l'input non corrisponde al formato (lettere al posto di cifre), scanf si ferma e i caratteri restano nel buffer: un ciclo che richiama scanf senza svuotarlo gira all'infinito.
Leggere una riga: fgets
char riga[100];
if (fgets(riga, sizeof riga, stdin) != NULL) {
riga[strcspn(riga, "\n")] = '\0'; /* toglie il '\n' finale, se c'è (string.h) */
}fgets(buf, n, flusso) legge al più n - 1 caratteri fino a '\n' incluso e aggiunge '\0'; restituisce NULL a fine file o in caso di errore. Non usare mai gets (eliminata dallo standard: non controlla la dimensione). Da una riga letta si estraggono i valori con sscanf(riga, "%d %d", &a, &b).
File
#include <stdio.h>
int main(void) {
FILE *f = fopen("dati.txt", "r");
if (f == NULL) {
perror("dati.txt"); /* stampa il motivo (es. file inesistente) */
return 1;
}
int x, n = 0;
double somma = 0;
while (fscanf(f, "%d", &x) == 1) {
somma += x;
n++;
}
fclose(f);
FILE *out = fopen("media.txt", "w");
if (out == NULL) {
perror("media.txt");
return 1;
}
if (n > 0)
fprintf(out, "media = %.2f\n", somma / n);
fclose(out);
return 0;
}| Funzione | Uso |
|---|---|
fopen(nome, modo) |
apre; modi "r", "w" (crea/svuota), "a" (aggiunge), "rb"/"wb" binari; NULL se fallisce |
fclose(f) |
chiude e scarica il buffer su disco |
fprintf(f, ...), fscanf(f, ...) |
come printf/scanf su un file |
fgets(buf, n, f), fputs(s, f) |
riga per riga |
fgetc(f), fputc(c, f) |
carattere per carattere; fgetc restituisce int per poter distinguere EOF |
feof(f) |
vero dopo che una lettura ha incontrato la fine del file |
Lettura carattere per carattere:
int c; /* int, non char */
while ((c = fgetc(f)) != EOF) {
if (c == '\n') righe++;
}Segnalare gli errori senza eccezioni
In C non ci sono eccezioni (Eccezioni in PythonEccezioni e traceback, eccezioni predefinite più comuni, try/except/else/finally, raise per segnalare errori, propagazione lungo le chiamate.Eccezioni in Python →): le funzioni segnalano il fallimento con un valore di ritorno speciale (NULL, EOF, numero di elementi letti minore del previsto, codice negativo) che il chiamante deve controllare. main restituisce un codice diverso da 0 per indicare un errore al sistema operativo.
Errori tipici
scanf("%d", n)senza&:scanfscrive all'indirizzo dato dal valore (casuale) din→ crash.%finvece di%lfper leggere undouble.while (!feof(f)) { fscanf(...); ... }: l'ultimo valore viene elaborato due volte o si elabora un valore non letto. Controllare il valore di ritorno difscanf.- Non controllare che
fopenabbia restituito un puntatore valido. - Mescolare
scanf("%d")efgets: il'\n'lasciato dascanfviene letto dafgetscome riga vuota.