我在使用C语言进行编程时遇到问题,尤其是在Visual Studio中使用fopen时。我阅读了fopen_s
函数并将以下行添加到我的项目中,但它仍然不起作用。
_CRT_SECURE_NO_WARNINGS
所以我尝试以这种方式使用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);
它还在崩溃。怎么了?
答案 0 :(得分:9)
即使打开失败,您也会将fclose
与fp
值无效使用。至少在{}
分支周围添加else
。
许多开发人员认为在任何地方使用大括号通常都是个好主意,即使其中有一个语句也是如此。如果你不这样,即使是经验丰富的开发人员也很容易犯这样的错误。所以把它们放在然后分支周围。
答案 1 :(得分:4)
_s
函数是不可移植的Microsoft发明,这些函数在很大程度上是在更易于移植的名称下已经存在的重复功能。此外,盲目地从函数的非_s
变体更改为_s
变体通常会不修复任何内容。 (例如,静默截断字符串不那么灾难性而不是破坏堆栈,但它仍然是可以被利用的错误行为。)
您的问题 - 不受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;
}
请注意标记为// HERE
的行如何打印两者传递给fopen
的确切字符串和strerror(errno)
的结果。每当系统调用失败时,您必须打印参数和strerror(errno)
。 (注意:如果您最终使用其中一个返回错误代码的_s
函数而不是设置errno
,那么您必须将返回值传递给strerror
。)
更改您的程序以执行此操作,您将能够找出为什么它无法正常工作。
答案 2 :(得分:1)
在Windows上,斜杠与Linux上的斜杠不同,因此您可以考虑使用C:\ File.txt而不是C:/File.txt。
答案 3 :(得分:0)
//试一试,它正在发挥作用。
#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 :(得分:-3)
关于您用来打开的模式,
err = fopen_s(&fp, "C:/File.txt", "rt")
我从未使用字母t作为参数而不知道那是什么......
但你正在用R(读)开头并尝试写......
尝试
err = fopen_s(&fp, "C:/File.txt", "w")
或
err = fopen_s(&fp, "C:/File.txt", "w+")
另外,你真的不需要err变量。如果fopen调用失败,则指针将为NULL。