0
#include <stdlib.h>
#include <stdio.h>


int main() {
   char ch, file_name[25];
   FILE *fp;

   printf("Enter the name of file you wish to see\n");
   gets(file_name);

   fp = fopen(file_name,"r"); // is for read mode

   if (fp == NULL) {
      printf(stderr, "There was an Error while opening the file.\n");
      return (-1);
   }

   printf("The contents of %s file are :\n", file_name);

   while ((ch = fgetc(fp)) != EOF)
         printf("%c",ch);

   fclose(fp);
   return 0;
}

このコードは機能しているように見えますが、「警告: このプログラムは gets() を使用していますが、これは安全ではありません」という警告が表示され続けます。

そのため、 fgets() を使用しようとしましたが、「関数呼び出しに必要な引数が少なすぎます 3」というエラーが表示されます。

これを回避する方法はありますか?

4

3 に答える 3

2

最初:決して使用しないgets()でください..バッファオーバーフローを引き起こす可能性があります

2 番目: どのように使用したかを示してくださいfgets()。正しい方法は次のようになります。

fgets(file_name,sizeof(file_name),fp); // if fp has been opened
fgets(file_name,sizeof(file_name),stdin); // if you want to input the file name on the terminal

// argument 1 -> name of the array which will store the value
// argument 2 -> size of the input you want to take ( size of the input array to protect against buffer overflow )
// argument 3 -> input source

ご参考までに:

fgets\0末尾に文字を追加して、入力全体を文字列に変換します ..

十分なスペースがある場合は、入力 (stdin) からfgetsも取得\nします。 を取り除き、\n入力全体を文字列として作成するには、次のようにします。

   fgets(file_name,sizeof(file_name),stdin);

   file_name[strlen(file_name)] = '\0';
于 2013-11-03T00:00:09.833 に答える
1

はい: fgets3 つの引数が必要です: バッファー ( と同じgets)、バッファーのサイズ、および読み取り元のストリーム。あなたの場合、 buffer-size はで取得できsizeof file_name、読み取り元のストリームはstdin. 全体として、これはあなたがそれを呼び出す方法です:

fgets(file_name, sizeof file_name, stdin);

安全ではない理由getsは、読み込むバッファのサイズがわからない (できない) ためです。したがって、バッファがいっぱいになってもバッファへの書き込みを続けるため、バッファオーバーフローが発生しやすくなります。

fgetsバッファのサイズを提供するため、この問題はありません。

ADDIT :printf内部への呼び出しif( fp == NULL )は無効です。printf最初の引数として、出力ストリームではなく、形式が必要です。fprintf代わりに電話したいと思います。

最後に、 -condition で正しく検出するEOFには、としてwhile宣言する必要があります。必ずしも に収まるとは限りませんが、 に収まります(また を返します)。で引き続き印刷できます。chintEOFcharintgetcint%c

于 2013-11-03T00:00:16.263 に答える