web-dev-qa-db-ja.com

Cでのfopen_sの使用

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);

まだクラッシュしています。どうしましたか?

9
nikodamn

オープンに失敗した場合でも、fcloseを無効なfp値とともに使用します。追加 {}少なくともelseブランチの周り。

多くの開発者は、内部に1つのステートメントがある場合でも、どこでもブレースを使用することをお勧めします。経験豊富な開発者であっても、そうしないと、このような間違いを犯しやすくなります。したがって、それらもthenブランチの周りに配置します。

9
hyde

__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に戻り値を渡す必要があります。)

これを行うようにプログラムを変更すると、なぜが機能しないかを理解できるようになります。

4
zwol

WindowsではスラッシュはLinuxとは異なるため、C:/File.txtの代わりにC:\ File.txtを使用することを検討してください。

1
binit92

//試してみると、うまくいきます。

#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;
}
0