La Gestione Dell'errore
La Gestione Dell'errore
Esiste una variabile globale intera, definita nell'header errno.h che viene
settata nel caso in cui una chiamata di sistema non possa eseguire
correttamente il suo compito. Tale variabile allora indica il tipo di errore
avvenuto.
#include <errno.h>
extern int errno;
Tale variabile può essere letta e scritta come ogni altra variabile.
In particolare il valore di questa variabile serve come indice per una
variabile di sistema che è un vettore di stringhe. Queste stringhe
contengono dei messaggi di errore caratteristici dell'errore avvenuto.
#include <stdio.h>
const char *sys_errlist[];
Nel caso una funzione di sistema ci avvisi di un errore possiamo farci
visualizzare a video (sullo standard error) la particolare stringa che ci
notifica l'errore, utilizzando la funzione
void perror(const char *str);
La stringa puntata da str viene visualizzata prima del messaggio di
errore.
Se l'ultima chiamata di sistema non ha causato errore, non si deve usare
errno, perchè il suo valore non è definito.
#include <stdio.h>
#include <errno.h>
void apri_file(void) {
FILE *finput;
finput=fopen("c:\\users\\input.txt","rt");
if ( finput==NULL ) {
perror("errore in funzione apri_file: ");
exit(0);
}
124
buffers di sistema, fine file ed errori.
125
INPUT / OUTPUT di BLOCCHI di byte da file
ANSI C mette a disposizione anche delle primitive che permettono di
leggere/scrivere su un file un blocco di byte di una dimensione
specificata. I prototipi di queste finzioni sono anch'essi contenuti
nell'header stdio.h, e tali funzioni sono:
126
Input di tipo diverso: PARAMETRI a RIGA di COMANDO
ANSI C mette a disposizione il modo di passare al programma dei parametri
nel momento in cui questo viene lanciato. Partendo ad es. da una shell di
comandi di Windows NT (una finestra simil DOS per intenderci) possiamo
far seguire al nome del programma una serie di caratteri separati da spazi,
che verranno copiati e passati sotto forma di stringhe in un vettore di
puntatori a char passati come argomento al main.
Il main dovrà essere a tal scopo definito come nell'esempio seguente, dove:
- argc indica il numero di parametri passati più uno (il nome del
programma).
- argv è un vettore di stringhe che contiene la riga di comando, in prima
posizione il nome del programma lanciato, nelle seguenti i parametri passati
Il programma stampa il numero dei parametri passati a riga di comando
compreso il nome del programma, e poi li stampa ad uno ad uno
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
printf("argc=%d { ",argc);
for ( i=0; i<argc; i++)
printf("%d:%s ", i, argv[i]);
printf("}\n");
}
Se il programma si chiama param, puo' essere eseguito "lanciandolo" dalla
shell di comando mediante una delle seguenti linee di comando, ottenendo
come output:
127
I/O di Basso Livello: i descrittori di file
Abbiamo in precedenza visto che è possibile effettuare I/O da file,
utilizzando primitive di tipo fopen, fread fwrite, fscanf, fgets. Tali
operazioni sono però limitate ai file.
Quello che si vorrebbe avere a disposizione sono delle primitive che
possono agire indifferentemente su file o su dispositivi di I/O di tipo
diverso, quali interfacce di rete, interfacce seriali ecc. Si vorrebbe cioè poter
utilizzare una stessa primitiva per accedere a entità di tipo diverso.
Esistono a tale scopo delle funzioni di librerie cosiddette per l'I/O di basso
livello, che permettono di operare su diversi device. Vengono ad esempio
utilizzate per scrivere applicazioni per comunicazioni via rete.
Ogni dispositivo per I/O, verrà aperto con una funzione detta open che
restituisce un intero detto "descrittore di file". Questo numero intero
rappresenta un indice per una struttura dati che descrive le modalità con cui
operare sul dispositivo. Tale descrittore verrà utilizzato in tutte le chiamate
per l'effettuazione di I/O.
Poichè queste istruzioni sono di basso livello, non esiste più distinzione tra
file di testo e file binari. Tutti i file sono visti come concatenazione di byte.
128
#include <stdio.h>
#include <fcntl.h>
129