[Question 1]
When I open a file into a function, generally I do something like this:
int read_file (char *filename)
{
FILE *fin;
if ( !(fin = fopen(filename, "r")) )
return 1;
/* ... */
return fclose(fin);
}
int main ()
{
char filename[100];
if ( read_file(filename) )
{
perror(filename);
exit(1);
}
return 0;
}
Generally 0
return value is for errors (right?) then I can change the previous code into:
int read_file (char *filename)
{
FILE *fin;
if ( !(fin = fopen(filename, "r")) )
return 0;
/* ... */
return !fclose(fin);
}
int main ()
{
char filename[100];
if ( !read_file(filename) )
{
perror(filename);
exit(1);
}
return 0;
}
But I think that the first code is more clean.
Another option is only change return 1;
into return -1;
(in the first code that I wrote).
What's the best version?
[Question 2]
If I must handle more errors, is it correct a code like this?
int read_file (char *filename, int **vet)
{
FILE *fin;
if ( !(fin = fopen(filename, "r")) )
{
perror(filename);
return 1;
}
* vet = malloc (10 * sizeof(int));
if ( *vet == NULL )
{
perror("Memory allocation error.\n");
return 1;
}
/* ... */
return fclose(fin);
}
int main ()
{
char filename[100];
int *vet;
if ( read_file(filename, &vet) )
exit(1);
return 0;
}
Re Q1:
a) Most POSIX functions actually return -1 (or <0) for errors, not 0. Look at (for instance) open()
, close()
, read()
, write()
and so forth. The exception is the POSIX calls that return pointers, e.g. fopen()
, which returns a FILE *
. These return NULL
on error.
b) I code my code to work like POSIX functions, which is similar the innards of many linux programs. I would call this 'the UNIX C standard'. However, many C++ programs and Java programs use true
for success and false
for failure. When these programmers move to C, they use 1 for success, and 0 for failure. This isn't wrong, but does cause confusion (well, causes me confusion). The worst result is when both standards are used in the same program. Picking a standard and sticking to it is more important than which standard you choose.
c) My own choice (in relation to Q1), would be to return -1
on error (i.e. as per your 'another choice' line).
Re Q2: mostly right, yes.
a) If your program is successful, better to exit(0)
than return 0
I believe.
b) Quite where you perror
is up to you. Perhaps you want to print the error in main()
.
c) Using perror
immediately followed by exit(1)
(or perhaps a different exit code depending on the error) is reasonable normal if you have no clean up to do or clean up within atexit
.
d) If you are returning the result of fclose()
on error, then the return if fopen
fails should be -1
(or EOF
) not 1 as if fclose()
fails it returns EOF
(otherwise known as -1
).
e) Nit: your main
function should have parameters (e.g. int main(char **argv, int argc)
)