Π.χ....
- Μορφοποιημένος Κώδικας: Επιλογή όλων
-
enum ErrId {
STARTERR = -1, /* not an id, just a limit*/
ERR_NOERROR = 0,
ERR_MEM,
ERR_RFILE,
ERR_WFILE,
ERR_PARAM,
ENDERR /* not an id, just a limit */
};
/* table of strings (or 2d array of char) */
char *errmsg[] = {
"No error",
"Out of memory",
"Read file error",
"Write file error"
"Invalid parameter"
};
/* -------------------------------------------- */
enum ErrID file_read( const char *fname )
{
FILE *fp = NULL;
if ( !fname )
return ERR_PARAM;
if ( NULL == (fp = fopen(fname, "r")) )
return ERR_RFILE;
...
fclose(fp);
return ERR_NOERROR;
}
/* -------------------------------------------- */
int main( void )
{
enum ErrId errid = NO_ERROR;
if ( (errid=file_read(...)) != NO_ERROR )
puts( errmsg[ errid ] );
...
}
Μπορείς το errid να το περνάς by-reference στην file_read() και να το ενημερώνεις μέσα της (ώστε να απελευθερώσεις την τιμή επιστροφής της συνάρτησης, σε κάτι άλλο... π.χ. τον αριθμό των bytes που διάβασε).
Ή μπορείς το errid να το κάνεις καθολική μεταβλητή, ώστε να μην το περνάς καν σαν όρισμα και να το ενημερώνεις απευθείας. Προφανώς θα πρέπει να το ελέγχεις κατόπιν, στην main(), μετά από την κλήση της κάθε σου συνάρτησης.
Έτσι δουλεύει η στάνταρ βιβλιοθήκη <errno.h> που ορίζει καθολικά την μεταβλητή errno, που την χρησιμοποιούν συναρτήσεις άλλων βιβλιοθηκών (π.χ. η strtol() ) για να δηλώσουν περισσότερες πληροφορίες από ότι η τιμή επιστροφής τους σε περίπτωση αποτυχίας... Οπότε όταν π.χ. καλείς την strtol() και σου επιστρέψει 0, για να δεις αν αυτό το 0 είναι ένδειξη αποτυχίας ή όχι, κάνεις το εξής:
α) πριν καλέσεις την strtol() μηδενίζεις την errno
β) μετά την κλήση της strtol() ελέγχεις αν το errno είναι διάφορο του μηδενός (το μηδέν σημαίνει "no error").
- Μορφοποιημένος Κώδικας: Επιλογή όλων
-
#include <stdio.h>
#include <stdlib.h> /* for strtol() */
#include <errno.h>
#define MAXINPUT (256+1)
int main( void )
{
char input[ MAXINPUT ] = {'\0'};
long int n, try;
printf( "Enter a long integer: " );
fgets( input, MAXINPUT, stdin );
errno = 0;
try = strtol(input, NULL, 10);
if ( 0L == try && errno != 0 )
perror( NULL ); /* μετατρέπει το τρέχον errno σε μήνυμα και το τυπώνει */
else
n = try;
...
}
* perror()
** η strtol() μπορεί να δώσει ακόμα περισσότερες πληροφορίες, μέσω του 2ου ορίσματός της, αν ΔΕΝ της το περάσεις ως NULL.
Ξέφυγα τελείως όμως. Αυτό που ξεκίνησα να πως είναι πως το errmsg[] είναι ένας πίνακας από strings, δηλαδή το κάθε στοιχείο του είναι ένας πίνακας από χαρακτήρες (και μάλιστα διαφορετικού μήκους, πολύ βολικό γιατί εξοικονομεί μνήμη).
Απλά στο παράδειγμά μου, χρειάζεται ΜΕΓΑΛΗ προσοχή ώστε οι enumerators να βρίσκονται σε ΑΠΟΛΥΤΗ αντιστοιχία με τα indices του errmsg[].



