37

Visual Studio is complaining about fopen. I can't find the proper syntax for changing it. I have:

FILE *filepoint = (fopen(fileName, "r"));

to

FILE *filepoint = (fopen_s(&,fileName, "r"));

What is the rest of the first parameter?

Spencer
  • 1,924
  • 15
  • 27
beatleman
  • 685
  • 2
  • 7
  • 11

1 Answers1

50

fopen_s is a "secure" variant of fopen with a few extra options for the mode string and a different method for returning the stream pointer and the error code. It was invented by Microsoft and made its way into the C Standard: it is documented in annex K.3.5.2.2 of the most recent draft of the C11 Standard. Of course it is fully documented in the Microsoft online help. You do not seem to understand the concept of passing a pointer to an output variable in C. In your example, you should pass the address of filepoint as the first argument:

errno_t err = fopen_s(&filepoint, fileName, "r");

Here is a complete example:

#include <errno.h>
#include <stdio.h>
#include <string.h>
...
    FILE *filepoint;
    errno_t err;
    
    if ((err = fopen_s(&filepoint, fileName, "r")) != 0) {
        // File could not be opened. filepoint was set to NULL
        // error code is returned in err.
        // error message can be retrieved with strerror(err);
        fprintf(stderr, "cannot open file '%s': %s\n",
                fileName, strerror(err));
        // If your environment insists on using so called secure
        // functions, use this instead:
        char buf[strerrorlen_s(err) + 1];
        strerror_s(buf, sizeof buf, err);
        fprintf_s(stderr, "cannot open file '%s': %s\n",
                  fileName, buf);
    } else {
        // File was opened, filepoint can be used to read the stream.
        ...
        fclose(filepoint);
    }

Microsoft's support for C99 is clunky and incomplete. Visual Studio produces warnings for valid code, forcing the use of standard but optional extensions but in this particular case does not seem to support strerrorlen_s. Refer to Missing C11 strerrorlen_s function under MSVC 2017 for more information.

To make matters worse, the Microsoft implementation of many of their secure functions have different semantics from the standard one documented in Annex K, which caused other systems to reject these functions and refuse to implement them. It is therefore recommended to avoid them for portability's sake.

In order to use standard functions such as fopen() with Visual Studio, you can add these 3 lines at the beginning of your source files, before the first #include directive:

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

The example becomes:

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <errno.h>
#include <stdio.h>
#include <string.h>
...
    FILE *filepoint;
    
    if ((filepoint = fopen(fileName, "r")) == NULL) {
        // File could not be opened. filepoint was set to NULL
        // error code was stored in errno.
        // error message can be retrieved with strerror(err);
        fprintf(stderr, "cannot open file '%s': %s\n",
                fileName, strerror(errno));
    } else {
        // File was opened, filepoint can be used to read the stream.
        ...
        fclose(filepoint);
    }
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 2
    strerror has a similar problem to fopen. Consider revising to show use of strerror_s for a +1 from me? – Assimilater Apr 15 '16 at 20:34
  • 3
    @Assimilater: there is no real *problem* with `fopen`. Visual Studio might produce a warning, prompting users to write less portable code with `fopen_s()`. The added semantics in `fopen_s` regarding the default permissions and the exclusive mode are best addressed with `fdopen` when available. `strerror_s` requires the user to provide a buffer whose length should be computed first by calling `strerrorlen_s(err)`. A headache hardly worth the trouble. – chqrlie Apr 16 '16 at 19:15
  • @Assimilater: Nevertheless, I edited the answer and provided code for both approaches. – chqrlie Apr 16 '16 at 19:21
  • I meant that when I used strerror(err) I got the same warning from visual studio (which prevented me from compiling) that I did with fopen. :/ – Assimilater May 10 '16 at 03:54
  • I didn't downvote but it complains about strerrorlen_s is unknown identifier. using vs 2013 – nurp Nov 24 '17 at 14:54
  • 1
    @nurp: Microsoft's support for C99 is clunky and incomplete. VS produces warnings for valid code, forcing the use of optional standard extensions but in this particular case does not seem to support the `strerrorlen_s`. Refer to https://stackoverflow.com/questions/44430141/missing-c11-strerrorlen-s-function-under-msvc-2017 for more information. – chqrlie Nov 25 '17 at 11:35