Using fopen_s in C

孤街醉人 提交于 2021-02-04 11:33:47

问题


I have a problem with programming in C, especially with fopen in Visual Studio. I read about the fopen_s function and added the following line to my project, but it still doesn't work.

_CRT_SECURE_NO_WARNINGS

So I tried using fopen_s in this way:

FILE *fp;
errno_t err;
if ((err = fopen_s(&fp, "C:/File.txt", "rt")) != 0)
    printf("File was not opened\n");
else
    fprintf(fp, "Date: %s, Time: %s, Score: %i \n", __DATE__, __TIME__, score);
fclose(fp);

It's still crashing. What's wrong?


回答1:


You use fclose with an invalid fp value, even if opening failed. Add {} around the else branch, at least.

Many developers think it is generally a good idea to use braces everywhere, even with one statement inside them. It's so easy to make a mistake like this if you don't, even for experienced developers. So put them around the then branch too.




回答2:


The _s functions are unportable Microsoft inventions which, for the most part, duplicate functionality that already existed under a more portable name. Moreover, blindly changing from the non-_s variant of a function to the _s variant generally does not fix anything. (For instance, silently truncating a string is less disastrous than clobbering the stack but it is still misbehavior which may be exploitable.)

Your problem -- which is not affected by the difference between fopen and fopen_s -- is almost certainly that you are not bothering to check for errors properly. Here is how to check for errors properly:

#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int argc, char **argv)
{
    FILE *fp;

    if (argc != 2) {
        fprintf(stderr, "usage: %s filename\n", argv[0]);
        return 2;
    }

    fp = fopen(argv[1], "rb");
    if (!fp) {
        fprintf(stderr, "opening %s: %s\n", argv[1], strerror(errno)); // HERE
        return 1;
    }

    // use 'fp' here...

    return 0;
}

Notice how the line marked // HERE prints both the exact string that was passed to fopen and the result of strerror(errno). It is absolutely essential that you print both the arguments and strerror(errno) whenever a system call fails. (Note: If you do wind up using one of the _s functions that returns an error code rather than setting errno, then you must pass the return value to strerror instead.)

Change your program to do this and you will be able to figure out why it isn't working.




回答3:


//give it a shot, it's working.

#include <stdio.h>
#include <tchar.h>
#include<iostream>
using namespace std;
int main()
{
    int score = 10;
    FILE *fp;
    errno_t err;
    if ((err = fopen_s(&fp, "C:\\Users\\achea\\Desktop\\File.txt", "w+")) != 0)
    {
        printf("File was not opened\n");
    }
    else
    {
        fprintf(fp, "Date: %s, Time: %s, Score: %i \n", __DATE__, __TIME__, 
        score);
    }
    fclose(fp);
    return 0;
}



回答4:


On Windows the slashes are different than on Linux, so you may consider using C:\File.txt instead of C:/File.txt.




回答5:


Regarding the mode you are using to open,

 err = fopen_s(&fp, "C:/File.txt", "rt")

I never used the letter t as a parameter and don't know what that is for...

But you are opening with R (read) and trying to write...

Try

 err = fopen_s(&fp, "C:/File.txt", "w")

or

 err = fopen_s(&fp, "C:/File.txt", "w+")

Also, you don't really need the err variable. If the fopen call fails, the pointer will be NULL.



来源:https://stackoverflow.com/questions/24127117/using-fopen-s-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!