11

I do not understand why this is seemingly failing with errno of 2:

char debugText [256];
sprintf (debugText, "C:\\List.txt");
dfile = fopen( debugText, "w");
fprintf ( dfile, "  err %d \n", errno);

I say seemingly because while dfile is NULL the file gets created and is filled with my output.

so what is going on ?

JPM
  • 445
  • 1
  • 5
  • 15
  • What type is `dfile`? Where's the test for `NULL`? – David Schwartz Apr 01 '13 at 22:35
  • 4
    take a look at `strerror()` which return a string that explains `errno` for you. – Zaffy Apr 01 '13 at 22:53
  • (For the googlers)For me it was that the file had no write permissions. On Windows: Right click > Properties > Security > Edit. Then allow modify for all users – Sergio Basurco Jan 14 '16 at 07:58
  • @SergioBasurco Perhaps it is a better fix, to make the file point to a location where regular users are allowed to write. Not everyone has administrator access at their pc and those rights should not be used to correct programming errors. – hetepeperfan May 18 '21 at 07:32

5 Answers5

15

All this tells you is that errno had the value 2 after your fopen call. You don't know that the call failed, because you didn't check whether dfile == NULL. If the output was actually written to the file, presumably the fopen call succeeded and the errno value was left over from some previous call, likely one you didn't make explicitly.

It's entirely possible for a successful call to fopen to set errno to a non-zero value.

Failing calls can set errno to some non-zero value, but successful calls don't set errno to 0. To check for errors, you need to

  • Set errno to 0 before the call;
  • Make the call and check the value it returned to see whether it succeeded or failed; and
  • Check the value of errno after the call -- but only if you know it failed (otherwise the value of errno is meaningless).

If dfile == NULL, then the fprintf call has undefined behavior; it will probably fail.

On the other hand, you say that dfile is NULL. How do you know that? Your code doesn't check it. (If the fopen call really did fail, could the contents of C:\List.txt be left over from a previous run of your program?)

What output do you get from this program?

#include <stdio.h>
#include <errno.h>
int main(void) {
    char debugText [256];
    FILE *dfile;

    sprintf (debugText, "C:\\List.txt");
    dfile = fopen( debugText, "w");
    if (dfile == NULL) {
        printf("fopen failed, errno = %d\n", errno);
    }
    else {
        printf("fopen succeeded\n");
    }
    return 0;
}
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • I see dfile is NULL 'cause i am stepping through in debug mode. that is when i started grabbing errno. – JPM Apr 02 '13 at 03:31
  • You need to check whether `defile == NULL` *in your program*, and then not try to write to the file if it is. To verify why `fopen()` fails, do as I suggested with `errno`. Assuming you're on a Windows system, opening `"C:\\List.txt"` for output shouldn't fail with `errno==2`, which means "No such file or directory". (You *are* on Windows, right? And not under Cygwin?) – Keith Thompson Apr 02 '13 at 05:01
  • @JPM: Try the program I just added to my answer. – Keith Thompson Apr 02 '13 at 05:12
9
2 ENOENT No such file or directory.  A component of a specified pathname
         did not exist, or the pathname was an empty string.

Here is a list of the error codes:

http://www.thegeekstuff.com/2010/10/linux-error-codes/

But you should check if fopen() returned NULL first because this value in errno might be left over from something else.

Johnny Mnemonic
  • 3,822
  • 5
  • 21
  • 33
5

No library function ever sets errno to zero.

You should only check errno after a function reports an error.

For example, your code should be:

if ((dfile = fopen(debugText, "w")) == 0)
    ...then fopen() failed and errno is relevant...

If the function does not report failure, the value in errno may be anything. For example, on Solaris, you often end up with errno set to ENOTTY after a successful operation, because stdout is not connected to a terminal. It doesn't mean anything actually went wrong; it just means that a test for whether standard output is a terminal failed (because it isn't a terminal).

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • if file did exist fopen is supposed to delete and then create a new. clearly the path is not empty nor is the path non-existant: C:\ so what i dont get is why dfile is NULL. unless THAT is an aberratioin of VS2010 ? – JPM Apr 02 '13 at 03:34
  • You don't prove that `dfile == NULL`; indeed, since the following `fprintf()` uses it, it is improbable that `dfile` is null (you'd probably get a crash in `fprintf()` if it was null). You'd have to revise your code to explicitly test `dfile` before I'd be willing to believe your assertion that `dfile` is null (and report the error on a channel other than `dfile`). – Jonathan Leffler Apr 02 '13 at 04:07
3

Only write filename: like below example works fine for me: It will create file and write number entered by user in it.

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
void main() {
    int num;
   FILE *fptr;
   clrscr();
   fptr = fopen("num.txt","w");

   if(fptr == NULL)
   {
     fprintf(stderr,"open error for %s,errno = %d: %s\n",fptr, errno, strerror(errno));
     printf("Error!");
     exit(1);
   }

   printf("Enter num: ");
   scanf("%d",&num);

   fprintf(fptr,"%d",num);
   fclose(fptr);

   getch();

}

1

In my case I got errno == 2 while trying to open file for writing on mounted flash drive with FAT file system; it turns out that if file doesn't comply with 8.3 rule, fopen returns NULL and sets errno to ENOENT.

It's necessary to say though, that I came across this situation on embedded system, and it shouldn't be the issue on Windows.

Andrey Starodubtsev
  • 5,139
  • 3
  • 32
  • 46