C语言 在 C 中使用 fopen_s

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24127117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:09:00  来源:igfitidea点击:

Using fopen_s in C

cvisual-c++fopen

提问by nikodamn

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

我在用 C 编程时遇到问题,尤其是在 Visual Studio 中使用 fopen。我阅读了该fopen_s函数并将以下行添加到我的项目中,但它仍然不起作用。

_CRT_SECURE_NO_WARNINGS

So I tried using fopen_sin this way:

所以我尝试fopen_s以这种方式使用:

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?

它仍然崩溃。怎么了?

采纳答案by hyde

You use fclosewith an invalid fpvalue, even if opening failed. Add {}around the elsebranch, at least.

即使打开失败,您也使用fclose无效fp值。至少{}else分支周围添加。

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 thenbranch too.

许多开发人员认为在任何地方都使用大括号通常是个好主意,即使其中包含一个语句。如果不这样做,很容易犯这样的错误,即使对于有经验的开发人员也是如此。所以也把它们放在then分支周围。

回答by zwol

The _sfunctions 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-_svariant of a function to the _svariant generally does notfix anything. (For instance, silently truncating a string is less disastrousthan clobbering the stack but it is still misbehavior which may be exploitable.)

这些_s功能是不可移植的 Microsoft 发明,在大多数情况下,它们复制了已经存在于更可移植名称下的功能。此外,盲目从非改变_s功能的变体的_s变异一般不会解决任何事情。(例如,默默地截断一个字符串比破坏堆栈更不具有灾难性,但它仍然是可能被利用的不当行为。)

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

您的问题——不受fopen和之间差异的影响fopen_s——几乎可以肯定是您没有费心去正确检查错误。以下是正确检查错误的方法

#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 // HEREprints boththe exact string that was passed to fopenand 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 _sfunctions that returns an error code rather than setting errno, then you must pass the return value to strerrorinstead.)

注意,此时的行标// HERE双方传递给确切的字符串fopen和结果strerror(errno)。打印参数和strerror(errno)系统调用失败时都非常重要。(注意:如果您确实使用_s了返回错误代码而不是设置的函数之一errno,那么您必须将返回值传递给strerror。)

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

更改您的程序以执行此操作,您将能够弄清楚它为什么不起作用。

回答by Achamyeleh Dagnaw

//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;
}

回答by binit92

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

Windows 上的斜杠与 Linux 上的不同,因此您可以考虑使用 C:\File.txt 而不是 C:/File.txt。

回答by vmp

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...

我从来没有用过字母 t 作为参数,也不知道它是干什么用的……

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

但是您正在使用 R(读取)打开并尝试编写...

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.

此外,您实际上并不需要 err 变量。如果 fopen 调用失败,则指针将为 NULL。