0

I have this code, note that it is shortened down. The problem is if the file exists it still overwrites it. Been 30 years since I did any programming so bear with me. Thanks!

FILE *openFil(FILE *open, char namn[]);

int main(int argc, const char * argv[])
{
    FILE *openFil(FILE *open, char namn[]);
    FILE *anmal =NULL;

    char filNamn[] = "ANMAL.DAT";
    postTypAnm pAnm;
    anmal = openFil(anmal, filNamn);
}

FILE *openFil(FILE *pointer, char name[])
{
    if ((pointer =fopen(name, "r+b"))== NULL)
        if ((pointer =fopen(name, "w+b"))== NULL)
        {
            /* It Enters here as well, but it should not do that or????? */
            printf("error\n");  
            exit(0);
        }
    return pointer;
}
alinsoar
  • 15,386
  • 4
  • 57
  • 74

3 Answers3

2

If you're using the C11 standard you can use the "x" argument to specify that if the file exists the fopen() function will fail.

For reference: http://www.cplusplus.com/reference/cstdio/fopen/

luv4bytes
  • 144
  • 7
  • 1
    Not an answer, maybe rewrite as a comment? – pmg May 31 '20 at 08:09
  • hmmm... the description of the `"x"` in [C11 7.21.5.3](http://port70.net/~nsz/c/c11/n1570.html#7.21.5.3) is *somewhat* different to the description on the link you posted. – pmg May 31 '20 at 08:20
  • Differs in what way? It states there as well that you would need to add the "x" specifier to the mode argument. – luv4bytes May 31 '20 at 08:27
  • The description in the link you posted does not mention *exclusive access*. – pmg May 31 '20 at 08:33
  • You're right, it doesn't mention that. Regarding the exclusive access the OP should have a look at the concepts of the OS that the program is written for. To see if the concepts of exclusive access are actually implemented. The link you posted is a better choise it seems. – luv4bytes May 31 '20 at 08:44
0

1.

"It Enters here as well, but it should not do that or?????"

No, It shouldn´t. If both pointers are NULL the opening of the streams to ANMAL.DAT were not successful, neither in w+b nor in r+b mode. Proof if the file really exist in the directory of the executable. Else try to use the entire path from the root directory to the file.

"The problem is if the file exists it still overwrites it."

Why do you know that the file is really overwritten in a proper manner?

Since if ((pointer =fopen(name, "r+b")) == NULL) and if ((pointer = fopen(name, "w+b"))== NULL) both fail, it seems that the ANMAL.DAT does not exist where fopen() searches for it or otherwise an error occurs when trying to open it (maybe has incorrect format or is corrupted?).

Place perror(name) in the error routine to check if errno was set to indicate an error at name.


2.

In the error routine: exit(0) is not correct if an error has happened. Use exit(EXIT_FAILURE).


Side note:

You have another prototype for the function openFil-> FILE *openFil(FILE *open, char namn[]); inside of main, which is redundant.

Also the identifier of the second parameter is different in the prototype before main to the identifier at the definition of openFil, namn in comparison to name.

Community
  • 1
  • 1
0

Here's a working example.

#include <errno.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

bool openFile(FILE **ptr,
    const char *fileName);

int main(int argc, const char * argv[]) {
    FILE *anmal = NULL;
    const char *fileName = "ANMAL.DAT";

    if(!openFile(&anmal, fileName)) {
        exit(EXIT_FAILURE);
    }
}

bool openFile(FILE **ptr,
    const char *fileName)
{
    *ptr = fopen(fileName, "w+bx");
    if(!*ptr) {
        perror("Error opening file: ");
        return false;
    }

    return true;
}

This is using the x extension in GNU C to test whether the file exists.

As other people have pointed out, there are numerous problems in your original code.

  • You've redeclared the function prototype for openFil within main.
  • In openFil there's no point in both accepting the FILE pointer as a parameter and overwriting it with the return value. Especially if you're expecting to input a NULL pointer and use the function to initialise it. Either use a pointer-to-pointer as a parameter so you can modify the pointer within the function, or ignore it completely and set its value with the function's return value. Not both.
  • You're not actually testing for whether the file exists at all. According to the manual pages for fopen (man fopen) neither of the flags you used in opening the file (r+ and w+) care whether the file exists. r+ opens for reading/writing and always positions the stream at the beginning of the file. w+ opens for reading/writing, truncating the file if it exists already. This explains why you didn't get the effect you intended.
ajxs
  • 3,347
  • 2
  • 18
  • 33