3

私は現在、Cベースのログパーサー(元のbashベースのログパーサーのCバージョンを作成)に取り組んでおり、入力が失敗した場合にバッファーオーバーフローを防ぐにはどうすればよいか疑問に思っていました。メモリが不足したときにプログラムを自動的に停止するために、以下のコードも提供しました。ありがとうございます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE
void main(int argc, char *argv[], char *envp[])
{
  FILE *fd;
  char *name;
  name = getenv("MCEXEC_PLAYERNAME");
  char *filename;
  filename = malloc(sizeof "/home/minecraft/freedonia/playerdata/deathlog-.txt" - 1 +    strlen(name) + 1);
  if (!filename) exit(EXIT_FAILURE);
  sprintf(filename,"/home/minecraft/freedonia/playerdata/deathlog-%s.txt",name);
  char buff[1024];
  if ((fd = fopen(filename, "r")) != NULL)
  {
    fseek(fd, 0, SEEK_SET);

    while(!feof(fd))
    {
      memset(buff, 0x00, 1024);
      fscanf(fd, "%[^\n]\n", buff);
    }
    printf("%s\n", buff);
  }
  else
  printf( "fail" );
}

以下のこのコードは、fgetsとscanfを実装する試みですが、プログラムを実行すると、出力が表示されずにそのまま表示されます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _GNU_SOURCE
void main(int argc, char *argv[], char *envp[])
{
  FILE *fd;
  char *name;
  name = getenv("MCEXEC_PLAYERNAME");
  char *filename;
  filename = malloc(sizeof "/home/minecraft/freedonia/playerdata/deathlog-.txt" - 1 +     strlen(name) + 1);
  if (!filename) exit(EXIT_FAILURE);
  sprintf(filename,"/home/minecraft/freedonia/playerdata/deathlog-%s.txt",name);
  char *buff;
  buff = malloc(1024);
  char *finbuff;
  finbuff = malloc(1024);
  if ((fd = fopen(filename, "r")) != NULL)
  {
    fseek(fd, 0, SEEK_SET);

    while(!feof(fd))
  {
      memset(buff, 0x00, 1024);
      memset(finbuff, 0x00, 1024);
     // fscanf(fd, "%[^\n]\n", buff);
      fgets(buff, 1024, fd);
      scanf(buff, "%[^\n]\n", finbuff);
   }
    printf("%s\n", finbuff);
  }
  else
  printf( "fail" );
}
4

2 に答える 2

5

を使用するのではなくfscanf、との組み合わせを使用する必要がfgetsありsscanfます...利点はfgets()、読み取られる最大バイト数を指定できるため、バッファオーバーフローを防ぐことができることです。次に、に置き換えsprintfますsnprintf

バッファオーバーフローを防ぐ基本的な方法は、書き込む最大バイト数を指定せずにバッファに書き込む関数を回避することです。

于 2012-05-10T15:29:47.037 に答える
1

@Jasonに同意します。

fgets()を使用して、テキストの行を文字配列に取得できます。文字配列はnullで終了します(つまり、文字列)。次に、sscanf()を使用して、テキストの各行が厳密な形式であると想定して、各行を解析できます。

次の投稿も役立つかもしれません。

fgetsとsscanf

于 2012-05-10T16:16:11.043 に答える