Salta al contenuto
Note per Studenti Input e output in C

Input e output in C

In questa pagina 6
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

c
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 */

Definizione (formato di printf). 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 →.

Esempio. printf("%d %5d %-5d|\n", 42, 42, 42) stampa 42 42 42 |.

scanf

c
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 & */

Proprietà (scanf: spazi bianchi, %s e valore di ritorno)

  • scanf salta gli spazi bianchi prima di %d, %lf, %s (non prima di %c: per saltarli si scrive " %c").
  • %s legge 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 EOF a 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;

Esempio. sscanf("12 7", "%d %d", &a, &b) restituisce 2, mentre sscanf("12 x", "%d %d", &a, &b) restituisce 1.

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

c
char riga[100];
if (fgets(riga, sizeof riga, stdin) != NULL) {
    riga[strcspn(riga, "\n")] = '\0';    /* toglie il '\n' finale, se c'è (string.h) */
}

Definizione (fgets). 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).

Esempio. Con char buf[5], fgets(buf, 5, stdin) su abcdefgh legge al più 44 caratteri e produce "abcd".

File

c
#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:

c
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 &: scanf scrive all'indirizzo dato dal valore (casuale) di n → crash.
  • %f invece di %lf per leggere un double.
  • while (!feof(f)) { fscanf(...); ... }: l'ultimo valore viene elaborato due volte o si elabora un valore non letto. Controllare il valore di ritorno di fscanf.
  • Non controllare che fopen abbia restituito un puntatore valido.
  • Mescolare scanf("%d") e fgets: il '\n' lasciato da scanf viene letto da fgets come riga vuota.

Versione ripasso

Tutto l'I/O standard è in <stdio.h>. Flussi: 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 →).

printf

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 →.

c
printf("%d %5d %-5d|\n", 42, 42, 42);   /* "42    42 42   |" */
printf("%.2f %8.3f\n", 3.14159, 2.5);   /* "3.14    2.500" */

scanf

c
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 & */
  • Salta gli spazi bianchi (tranne %c, per cui serve " %c").
  • %s legge una parola; la larghezza (%31s) evita overflow lasciando spazio a '\0'.
  • Valore di ritorno: numero di valori letti con successo o EOF. Va controllato.

Esempi: if (scanf("%d %d", &a, &b) != 2) { ...errore... }; while (scanf("%d", &x) == 1) somma += x; (somma fino a fine input).

Se l'input non corrisponde al formato, scanf si ferma e i caratteri restano nel buffer (ciclo infinito se non svuotato).

Leggere una riga: fgets

c
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 errore. Non usare mai gets. Estrazione valori: sscanf(riga, "%d %d", &a, &b).

File

c
FILE *f = fopen("dati.txt", "r");
if (f == NULL) { perror("dati.txt"); return 1; }
while (fscanf(f, "%d", &x) == 1) { /* elabora x */ }
fclose(f);
Funzione Uso
fopen(nome, modo) apre; "r", "w" (crea/svuota), "a", binari "rb"/"wb"; NULL se fallisce
fclose(f) chiude e scarica il buffer
fprintf(f, ...), fscanf(f, ...) come printf/scanf su file
fgets(buf, n, f), fputs(s, f) riga per riga
fgetc(f), fputc(c, f) carattere per carattere; fgetc restituisce int per distinguere EOF
feof(f) vero dopo che una lettura ha incontrato la fine del file

Lettura carattere per carattere: int c; while ((c = fgetc(f)) != EOF) { ... } (int, non char).

Segnalare gli errori senza eccezioni

Il C non ha 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 →); si usa un valore di ritorno speciale (NULL, EOF, conteggi errati) e main restituisce un codice diverso da 0 per gli errori.

Errori tipici

  • scanf("%d", n) senza & (crash).
  • Usare %f invece di %lf per un double.
  • while (!feof(f)) { fscanf(...); }: l'ultimo valore viene elaborato due volte.
  • Dimenticare di controllare il ritorno di fopen.
  • Mescolare scanf("%d") e fgets lasciando il '\n' nel buffer.

Esercizi su questo argomento

Teoria collegata