Salta al contenuto
Note per Studenti Input e output in C

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

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

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

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

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

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.

Teoria collegata