web-dev-qa-db-ja.com

fopen / fopen_sおよびファイルへの書き込み

Cでfopenを使用して、出力をテキストファイルに書き込みます。関数宣言は次のとおりです(ARRAY_SIZEは以前に定義されています):

void create_out_file(char file_name[],long double *z1){  
  FILE *out;  
  int i;  

  if((out = fopen(file_name, "w+")) == NULL){  
    fprintf(stderr, "***> Open error on output file %s", file_name);  
    exit(-1);  
  }  

  for(i = 0; i < ARRAY_SIZE; i++)  
    fprintf(out, "%.16Le\n", z1[i]);  
  fclose(out);  
}  

私の質問:

  1. MVS2008でコンパイルすると、次の警告が表示されます。警告C4996: 'fopen':この関数または変数は安全ではない可能性があります。代わりにfopen_sの使用を検討してください。コードを変更できるように、fopen_sに関する情報があまりありません。助言がありますか?

  2. fprintfに指示して、希望する数値精度で数値を書き込むことができますファイルへlong doubleを使用している場合、答えは小数点以下15桁まで問題ないと思います。私は正しいですか?

22
yCalleecharan

fopen_sfopenのバリアントであり、パラメータ検証を含み、オープンプロセス中に何か問題が発生した場合にポインターの代わりにエラーコードを返します。より多くのEdge条件を考慮するため、基本バリアントよりも安全です。 fopenはアプリケーションの潜在的な悪用ベクトルを表すため、コンパイラは使用するよう警告しています。

指定子%.xgを使用して、関数のprintfファミリーに精度の桁を指定できます。ここで、xは出力に必要な精度の桁です。 A long doubleは、プラットフォームごとに精度が異なりますが、一般に少なくとも16桁の10進精度であることに賭けることができます。

編集:fopen_scomplete時間の無駄であると示唆している他の人たちと完全に同席しているわけではありませんが、悪用される可能性はかなり低く、広くサポートされていません。 C4996で警告された他の機能のいくつかははるかに深刻な脆弱性ですが、_CRT_SECURE_NO_WARNINGSを使用することは、「寝室のドアのロックを解除した」と「核爆弾を残した」両方のアラームをオフにすることと同等ですキッチン"。

プロジェクトで「純粋なC」を使用することに制限されていない限り(学校の割り当てや組み込みマイクロコントローラーなど)、最新のCコンパイラのほとんどすべてがC++コンパイラでもあるという事実を活用して、セキュリティの互換性を同時に向上させるために、これらすべてのI/O関数のC++ iostreamバリアント。

20
Dan Story

私はVisual Studio 2012で動作する同様の問題に遭遇しましたが、私の問題が拡大した場所では、Visual Studioの機能をテストに使用し、最終的に同じアプリケーションをコンパイルして実行できるプログラムを構築していましたLinuxサーバー(ボットを作成しています)

だから、これは私がいくつかのGoogle-ingの後に思いついたものであり、それが他の誰かを助けるかもしれない場合に備えてそれを投稿すると思いました。

FILE *fp_config;
const char *configfile ;
configfile = "bot.conf";
#ifdef WIN32
    errno_t err;
    if( (err  = fopen_s( &fp_config, configfile, "r" )) !=0 ) {
#else
    if ((fp_config = fopen(configfile, "r")) == NULL) {
#endif
        fprintf(stderr, "Cannot open config file %s!\n", configfile);
    }

これはVisual Studioをなだめ、文句を言わず、gccまたは他の標準準拠のc/c ++コンパイラで同じコードをコンパイルできるようにします。

10
BrierMay
  1. fopen_sおよび他のすべての_s関数は、標準関数のMS固有の「安全な」バリアントです。コードがクロスプラットフォームである必要がない場合は、切り替えるだけでコンパイラを満足させることができます。それ以外の場合は、_CRT_SECURE_NO_WARNINGSプリプロセッサディレクティブをプロジェクト設定に追加すると、警告が表示されなくなります。

  2. ええ、long doubleは15桁の精度に適しています。実際には、通常のダブルスでも十分です(それ以上ではありません)。

6
tzaman

Fopenからfopen_sに移動すると、ファイルを開いて書き込み中にメモ帳(読み取り専用)でファイルを開く機能が無効になりました。 fopenに戻ると、プログラムがファイルを書き込む間、私は読むことができます。

4
eduard

_CRT_SECURE_NO_WARNINGSこの警告を取り除くためにファイルをインクルードする前に、MSがfopenについて言っていることを信じないようにする

1
Artyom