NULL returned by fopen - where is a list of what's causing the error?

F

ferrad

I am trying to open a file for appending. ie. if the file exists, open
it for appending, if not, create it. I am getting back a NULL pointer,
and do not know why. Here is my code:

FILE *pFile;
char *cFileName;
cFileName=argv[++i];
pFile = fopen(cFileName,"a+");

cFileName has a valid filename ('apm.dbg'), and I have full write
permissions in the directory. I can step into fopen and when the file
is opened, I can see in another window that the file is created with
zero bytes. However pFile is returned as NULL.

Is there a function call I can make to tell what the error actually is?
 
V

Vladimir S. Oka

ferrad said:
I am trying to open a file for appending. ie. if the file exists, open
it for appending, if not, create it. I am getting back a NULL pointer,
and do not know why. Here is my code:

FILE *pFile;
char *cFileName;
cFileName=argv[++i];
pFile = fopen(cFileName,"a+");

Your code is not compilable/runnable. E.g. what is 'i'?
cFileName has a valid filename ('apm.dbg'), and I have full write
permissions in the directory. I can step into fopen and when the file
is opened, I can see in another window that the file is created with
zero bytes. However pFile is returned as NULL.

Is there a function call I can make to tell what the error actually is?

AFAIK, the standard only specifies that fopen() returns NULL
when it fails for whatever reason:

7.19.5.3.8
The fopen function returns a pointer to the object controlling
the stream. If the open operation fails, fopen returns a null
pointer.

Cheers

Vladimir
 
M

Mike Wahler

ferrad said:
I am trying to open a file for appending. ie. if the file exists, open
it for appending, if not, create it. I am getting back a NULL pointer,
and do not know why. Here is my code:

FILE *pFile;
char *cFileName;
cFileName=argv[++i];
pFile = fopen(cFileName,"a+");

cFileName has a valid filename ('apm.dbg'), and I have full write
permissions in the directory. I can step into fopen and when the file
is opened, I can see in another window that the file is created with
zero bytes. However pFile is returned as NULL.

Is there a function call I can make to tell what the error actually is?

The only thing standard C says about the return value of
'fopen()' is that it will be NULL if the opening of the
file failed, and non-NULL if it succeeded.

Any particular reasons for failure will be platform-dependent.
You should consult your compiler and/or platform documentation
(e.g. for a list of 'error codes' which would give more
specific information). Many implementations provide extensions
for this very purpose.


-Mike
 
N

Nelu

ferrad said:
I am trying to open a file for appending. ie. if the file exists, open
it for appending, if not, create it. I am getting back a NULL pointer,
and do not know why. Here is my code:

FILE *pFile;
char *cFileName;
cFileName=argv[++i];
pFile = fopen(cFileName,"a+");

cFileName has a valid filename ('apm.dbg'), and I have full write
permissions in the directory. I can step into fopen and when the file
is opened, I can see in another window that the file is created with
zero bytes. However pFile is returned as NULL.

Is there a function call I can make to tell what the error actually is?
If you include string.h and errno.h you could use strerror(errno) to obtain
a string explaining the error.
 
E

Eric Sosman

ferrad wrote On 01/20/06 11:35,:
I am trying to open a file for appending. ie. if the file exists, open
it for appending, if not, create it. I am getting back a NULL pointer,
and do not know why. Here is my code:

FILE *pFile;
char *cFileName;
cFileName=argv[++i];
pFile = fopen(cFileName,"a+");

cFileName has a valid filename ('apm.dbg'), and I have full write
permissions in the directory. I can step into fopen and when the file
is opened, I can see in another window that the file is created with
zero bytes. However pFile is returned as NULL.

Is there a function call I can make to tell what the error actually is?

On many systems, the `errno' pseudo-variable may
give additional information about a failure. Try
something like

pFile = fopen(cFileName, "a+");
if (pFile == NULL) {
perror (cFileName);
die_or_maybe_proceed_to_next_file();
}

However, the C Standard doesn't promise that fopen()
will set `errno' on a failure, nor that the `errno'
value will be meaningful. On a system that doesn't
use `errno' for such things, you may get a misleading
message like "apm.dbg: socket type not supported" or
"apm.dbg: font not found," so consider what perror()
tells you but treat it with some skepticism.

Beyond that, the reasons fopen() might fail are
system-specific and not really "C reasons" at all.
You'll need to go snooping in your system's documentation
to see if there's a list of reasons for failure, and
even then it's quite possible the list is incomplete.
Good luck!
 
R

Richard Tobin

Is there a function call I can make to tell what the error actually is?

On many systems the function perror will give you a useful error
message when fopen fails.

-- Richard
 
F

ferrad

Thanks for all the replies. Yes I know it's not compilable, it's just
an code excerpt.
I have now got the error description:
- when the file does not exist, I get ERROR_NEGATIVE_SEEK returned
- when the file does exist, I get ERROR_ALREADY_EXISTS returned

In both cases a NULL is returned in pFile. The platform is Microsoft
VS7 .NET

Adrian
 
F

ferrad

A Google search gives:
- when the file does not exist:
ERROR_NEGATIVE_SEEK
// An attempt was made to move a file pointer before the beginning of
the file.

- when the file does exist:
ERROR_ALREADY_EXISTS
// The system cannot create a file when it already exists.

Seems strange to me sine "a+" meand append is it exists, create it if
it doesn't.
Adrian
 
V

Vladimir S. Oka

ferrad said:
A Google search gives:
- when the file does not exist:
ERROR_NEGATIVE_SEEK
// An attempt was made to move a file pointer before the beginning of
the file.

- when the file does exist:
ERROR_ALREADY_EXISTS
// The system cannot create a file when it already exists.

Seems strange to me sine "a+" meand append is it exists, create it if
it doesn't.
Adrian

Please quote what you're replying to (even yourself).

What you found is system specific (and may not even apply to
/your/ system). Also see Eric's post elsethread which explains
it better that I could right now.

Cheers

Vladimir
 
F

ferrad

The problem is actually caused by C / Fortran file format differences.
The text file is actually created, written to and closed in Fortran
first, then opened for appending in C as above. It appears that
something to do with the structure of the file in the two languages is
incompatible.
If anyone has some information on why C and Fortran can't write to the
same file, or what I have to do in C to get it to recognize the Fortran
text file, that would be appreciated.
Adrian
 
W

Walter Roberson

The problem is actually caused by C / Fortran file format differences.
The text file is actually created, written to and closed in Fortran
first, then opened for appending in C as above. It appears that
something to do with the structure of the file in the two languages is
incompatible.
Plausible.

If anyone has some information on why C and Fortran can't write to the
same file, or what I have to do in C to get it to recognize the Fortran
text file, that would be appreciated.

You mentioned earlier that you are using Windows. If I recall correctly,
the standard end of line marker used by Windows for a text file is
carriage return followed by linefeed. But when you create the file
in Fortran, are you telling FORTRAN that you are creating a text file?
If not, then it might be writing it using some internal FORTRAN binary
format that doesn't happen to use CR/LF .

In order to handle the file within C, you should open it in binary
mode (add "b" to the mode string, as in "rb" instead of "r"), and
then do whatever you need to do in order to decode the FORTRAN
line format.
 
F

ferrad

You mentioned earlier that you are using Windows. If I recall correctly,
the standard end of line marker used by Windows for a text file is
carriage return followed by linefeed. But when you create the file
in Fortran, are you telling FORTRAN that you are creating a text file?
If not, then it might be writing it using some internal FORTRAN binary
format that doesn't happen to use CR/LF .

Fortran writes a CR/LF at the end of each line.
In order to handle the file within C, you should open it in binary
mode (add "b" to the mode string, as in "rb" instead of "r"), and
then do whatever you need to do in order to decode the FORTRAN
line format.

I tried "ab" (append / binary), but still get the ERROR_ALREADY_EXISTS
error.

Adrian

PS. both Fortran and C DLLs are only trying to write to the file (no
reads).
 
F

ferrad

More investigation reveals that it doesn't matter where the text file
comes from (even written by C itself, so I think the Fortran bit above
is a red herring), the append mode of fopen does not appear to work.
Is this a non-standard C feature?
Adrian
 
F

ferrad

Actually, this whole thing is a VS.NET debugger aberration. The fopen
apparently returns a NULL pointer (and GetLastError() also is
non-zero), however when I execute fprintf on the pointer, the file
pointer becomes non-zero, and I write quite happily to the file.
Adrian
 
E

Emmanuel Delahaye

ferrad a écrit :
I am trying to open a file for appending.
ie. if the file exists, open
it for appending, if not, create it.

Why "a+" ? What's wrong with "a" ?
I am getting back a NULL pointer,
and do not know why. Here is my code:

FILE *pFile;
char *cFileName;
cFileName=argv[++i];
pFile = fopen(cFileName,"a+");

cFileName has a valid filename ('apm.dbg'), and I have full write
permissions in the directory. I can step into fopen and when the file
is opened, I can see in another window that the file is created with
zero bytes. However pFile is returned as NULL.

Is there a function call I can make to tell what the error actually is?

perror (cFileName);
 
E

Eric Sosman

RSoIsCaIrLiIoA said:

This is a possible improvement in that it might help
avoid nonsense messages from implementations that don't
set errno when fopen() fails.
if(errno) perror(cFileName)

This, however, is nonsense. See Question 20.4 in
the comp.lang.c Frequently Asked Questions (FAQ) list
at http://c-faq.com/ .
 
R

RSoIsCaIrLiIoA

This is a possible improvement in that it might help
avoid nonsense messages from implementations that don't
set errno when fopen() fails.
^;
i say "if(errno) perror(cFileName);" at place of "perror(cFileName)"
This, however, is nonsense. See Question 20.4 in
the comp.lang.c Frequently Asked Questions (FAQ) list
at http://c-faq.com/ .

where is the nonsense, is it because i don't print the file name in
case fopen fail? i don't have "faq" list
 
E

Eric Sosman

RSoIsCaIrLiIoA wrote On 01/31/06 17:34,:
^;
i say "if(errno) perror(cFileName);" at place of "perror(cFileName)"

Aha! I thought you intended to replace all of
`if (pFile == NULL) { perror(...); ...}' with
`if (errno) perror(...);'. (It's hard to make such
things clear simply by using indentation levels,
especially given the "> " quotation indicators.)
I retract my "nonsense" remark.
where is the nonsense, is it because i don't print the file name in
case fopen fail? i don't have "faq" list

No longer "nonsense," but still unreliable for the
reasons explained in the FAQ. You may not have that
estimable document ready to hand, but I assume you're
able to cut-and-paste a URL into a browser.
 
K

Keith Thompson

Eric Sosman said:
This is a possible improvement in that it might help
avoid nonsense messages from implementations that don't
set errno when fopen() fails.
Yes.


This, however, is nonsense. See Question 20.4 in
the comp.lang.c Frequently Asked Questions (FAQ) list
at http://c-faq.com/ .

Not necessarily. The standard doesn't say that fopen() sets errno, so
it's possible for fopen() to fail but for errno to remain 0. In that
case, the original code is likely to print something like:

foo.txt: No error

(I wonder why the standard doesn't require fopen() to set errno.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,270
Latest member
TopCryptoTwitterChannels_

Latest Threads

Top