[英]Using fopen_s in C
我在用 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);
它仍然崩潰。 怎么了?
即使打開失敗,您也可以使用帶有無效fp
值的fclose
。 至少在else
分支周圍添加{}
。
許多開發人員認為在任何地方都使用大括號通常是個好主意,即使其中包含一個語句。 如果不這樣做,很容易犯這樣的錯誤,即使對於有經驗的開發人員也是如此。 所以也把它們放在then分支周圍。
_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)
是絕對必要的。 (注意:如果您確實使用了返回錯誤代碼而不是設置errno
的_s
函數之一,那么您必須將返回值傳遞給strerror
。)
更改您的程序以執行此操作,您將能夠弄清楚它為什么不起作用。
//試一試,它正在工作。
#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;
}
Windows 上的斜杠與 Linux 上的不同,因此您可以考慮使用 C:\\File.txt 而不是 C:/File.txt。
關於您使用的打開模式,
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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.