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);
まだクラッシュしています。どうしましたか?
オープンに失敗した場合でも、fclose
を無効なfp
値とともに使用します。追加 {}
少なくともelse
ブランチの周り。
多くの開発者は、内部に1つのステートメントがある場合でも、どこでもブレースを使用することをお勧めします。経験豊富な開発者であっても、そうしないと、このような間違いを犯しやすくなります。したがって、それらもthenブランチの周りに配置します。
__s
_関数は、移植性のないMicrosoftの発明であり、ほとんどの場合、よりポータブルな名前ですでに存在していた機能を複製します。さらに、関数の非__s
_バリアントから__s
_バリアントに盲目的に変更すると、通常はnotで修正されます。 (たとえば、文字列をサイレントに切り捨てることは、スタックを破壊するよりも惨事が少ないですが、それでも不正行為であり、悪用される可能性があります。)
あなたの問題-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
_とマークされた行がbothを出力する方法に注意してください。fopen
に渡された正確な文字列とstrerror(errno)
の結果。システムコールが失敗した場合は常に、引数とstrerror(errno)
の両方を出力することが絶対に不可欠です。 (注:errno
を設定するのではなく、エラーコードを返す__s
_関数のいずれかを使用する場合は、代わりにstrerror
に戻り値を渡す必要があります。)
これを行うようにプログラムを変更すると、なぜが機能しないかを理解できるようになります。
WindowsではスラッシュはLinuxとは異なるため、C:/File.txtの代わりにC:\ File.txtを使用することを検討してください。
//試してみると、うまくいきます。
#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;
}