22

I'm working on a simple file splitter/merger program in the C programming language. The problem is, for some reason fopen returns NULL, and because of that, my program is crashing at the fwrite statement. How do I fix this?

Here is the C file:

int SplitFile(char* filename, char* output, size_t size)
{
    char current_file_name[256];
    int file_count = 0, i = 0;
    FILE *file = fopen( filename, "rb" );
    printf("split %s into chunks of %d named\n", filename, size);

    if (!file)
       return E_BAD_SOURCE;
    else
    {
        output = (char *) malloc(size * sizeof(char));
        if (output == NULL)
            return E_NO_MEMORY;
        else
        {
            int bytes_read = 0;
            FILE *outFile;
            do
            {
                bytes_read = fread(output, sizeof(char), size, file );
                sprintf(current_file_name, "%s%04lu\n", "part", file_count++);
                outFile = fopen (current_file_name, "wb" );  // THIS RETURNS NULL
                fwrite(output, sizeof(char), bytes_read, outFile); //CRASHES ON THIS LINE
            }
            while ( bytes_read > 0 )
                ;

            //fclose(outFile);
        }
    }
    fclose(file);
    printf("...\n");
    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
k787
  • 397
  • 2
  • 5
  • 11
  • 1
    Snarky - check the file opened before you try to write to it. The real answer is you probably don't have the file system permissions or it is in a folder path that doesn't exist – EnabrenTane May 13 '11 at 05:37
  • 11
    What error is stored into `errno`? Just add `if (!outFile)perror("fopen");` and let the library tell you why it failed. :) – sarnold May 13 '11 at 05:40
  • in errno I'm getting fopen : Invalid Argument – k787 May 13 '11 at 05:43
  • Are you giving the right path? – Shweta May 13 '11 at 05:44
  • it should use the default path( the folder which contains the .c and .h ). I don't thing it's related to path – k787 May 13 '11 at 05:48

8 Answers8

22

The proper thing to do is check errno when fopen returns NULL.

I'm going to guess that your problem is that you're trying to write to a filesystem that doesn't allow \n in filenames, but it could be a permissions issue as well.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gabe
  • 84,912
  • 12
  • 139
  • 238
  • 1
    The more proper thing to do is check errno when fopen returns NULL. You probably meant fopen instead of fwrite. – Windows programmer May 13 '11 at 05:44
  • when I comment out the sprintf and do this; outFile = fopen ( "part000" , "wb" ); it works fine. – k787 May 13 '11 at 05:50
  • @user: Have you taken the `\n` out of your `sprintf` line, then? – Gabe May 13 '11 at 06:00
  • yeah it worked when I took out the \n. Thanks a lot. But I don't understand why \n causing the fopen to return NULL. – k787 May 13 '11 at 06:06
  • 1
    @user: The `\n` character is not allowed in a filename. That causes `fopen` to fail, so it returns NULL. – Gabe May 13 '11 at 06:23
  • 1
    it would help to see an example of checking `errno`. that's why we're here, to learn :) – jenkizenki Mar 13 '20 at 21:53
  • @jenkizenki there's an example in this answer [this answer](https://stackoverflow.com/a/15753143/10564382) – jonyB Aug 01 '22 at 15:02
12

There are many reasons fopen can return NULL including (but certainly not limited to):

  • The file doesn't exist
  • The file is opened in a mode that doesn't allow other accesses
  • The network is down
  • The file exists, but you don't have permissions
  • A file exists with the name you gave, but the current directory of the process is not what you expected so the relative pathname fails to find and open the file.

The way to find out which is responsible is to dig into the errno code.

However just because you resolve this particular error doesn't mean you can assume fopen will never return NULL. When dealing with I/O operations your code simply has to expect failure. It's not possible to predict the success of I/O operations, and they can always fail.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • what about running out of space? wouldn't that make it return NULL? (i know you said "not limited to" my question is not rhetoric) – Nande Feb 19 '16 at 02:02
  • @Nande: `fopen()` that creates a new file may or may not succeed on a full disk. If the directory doesn't need expanding (and you're not out of inodes), it can succeed, but a following `fwrite()` (**or** `fclose()`!) will fail. – Davis Herring Sep 23 '17 at 23:45
2

It means that the file might not exist or some permission error occurred while accessing a file such as "Read-Only" or "Write-Protected", so in those cases fopen will return 0 (a NULL pointer). On success it will return a file pointer as a handler.

fp=fopen("c:\\ABC.txt", "r"); cannot be the same as fp=fopen("c:\\abc.txt", "r");.

Use // instead of \\ in a Linux environment.

P.S.: In Linux and Unix-like operating systems file names are case-sensitive.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sohail xIN3N
  • 2,951
  • 2
  • 30
  • 29
0

In Unix, for fopen(), there is no reason to prepend ./ to a filename passed to fopen().

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vinoj John Hosan
  • 6,448
  • 2
  • 41
  • 37
0

In my case, i was reading the same file all over again in a while loop and forgot to close it.

I used a function for reading the file and finding a match and the function had a return; statement that terminated the function before doing fclose(fp) :D

Riki137
  • 2,076
  • 2
  • 23
  • 26
0

The path given for the file is checked from wherever the executable is present. In my case I was opening the text file in c file when both were present at the same place. It was continuously giving the error of file not found. Placed the file in the folder of executable and it started working.

Sanya Tayal
  • 81
  • 1
  • 4
0

In my case, it was because I was trying to create the file in a directory that does NOT exist.

tuket
  • 3,232
  • 1
  • 26
  • 41
0

Is fopen for write return NULL in the first run?

I noticed that in the while you keep open files for write but not closing them.

Try to add fclose(outFile) after fwrite:

outFile =  fopen ( current_file_name , "wb" );    
fwrite(output, sizeof( char ), bytes_read, outFile); 
fclose(outFile)

It is possible you open more files than your OS allows.

Amir
  • 32
  • 3