问题
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