0

My program decodes an image that is covered by random pixels, to decode the image, I have to multiply each pixel's red color component by 10. The green and blue color components are the same values as the new red component. I've created multiple helper functions, to make the code easier to read in main, but when I try to run my a.out, I keep getting "Segmentation Fault". I can't seem to find my mistakes! Help is appreciated.

void check_argument(int arg_list)
{
   if (arg_list < 2)
   {
      perror("usage: a.out <input file>\n");
   }
}

void print_pixel(int a, FILE *out)
{
   int r, g, b;

   r = a * 10;

   if (r > 255)
   {
      r = 255;
   }

   g = r;
   b = r;

   fprintf(out, "%d\n", r);
   fprintf(out, "%d\n", g);
   fprintf(out, "%d\n", b);
}

void read_header(FILE *in)
{
   char str[20];

   for (int i = 0; i < 3; i++)
   {
      fgets(str, 20, in);
   }
}

FILE*  open_files(FILE *infile, char *input[])
{
   infile = fopen(input[1], "r");

   if (infile == NULL)
   {
      perror("Error: Cannot read file.\n");
   }

   return infile;
}

void decode(int arg_list, char *in[])
{
   FILE *input, *output;

   int check, red, green, blue;

   open_files(input, in);
   output = fopen("hidden.ppm", "w");

   fprintf(output, "P3\n");
   fprintf(output, "%d %d\n", 500, 375);
   fprintf(output, "255\n");

   read_header(input);
   check = fscanf(input, "%d %d %d", &red, &green, &blue);

   while (check != EOF)
   {
      print_pixel(red, output);
      check = fscanf(input, "%d %d %d", &red, &green, &blue);
   }

   fclose(input);
   fclose(output);
}

int main(int argc, char *argv[])
{
   check_argument(argc);
   decode(argc, argv);
}
4

2 に答える 2

0

これは宿題なので、一般的なバグの原因とその見つけ方を紹介します。

  1. 使用される変数は、その前に割り当てられる必要があります (すべきです)。これは、特にポインターの場合に重要ですFILE *

  2. 関数 (例: fopen()) が失敗した場合、通常は続行する前にチェックする必要がある特別な値を返すことでこれを示します。

  3. 変数が持つ値を確認するには、それを表示するために使用できますprintf()

これは、segfault などの主要なエラーを見つけるためのものです。

しかし、論理エラーも見つけるのが困難です。3 つの値を読み取って変数に格納する場合、それらの 1 つだけではなくすべてを使用する方が便利な場合があります。(しかし、これはまだこの演習の目標ではないかもしれません。)


この前の行を書いたのは、与えられたプログラムのバグを探すのではなく、自分でプログラムを書くことが仕事だと知る前だったので、ここでもう少し具体的に説明します。

AFILE *は によって返されるものfopen()です。それを返すか、「1レベル深い」ポインターによって間接的に指される変数または別のメモリ位置に書き込むことができます。

したがって、次のように書き換える必要がありますopen_files()(ところで: なぜ file* s * なのですか? 現在は 1 つだけです...):

値を返すためのいずれか(推奨):

FILE* open_files(char *input[])
{
   FILE *infile = fopen(input[1], "r");

   if (infile == NULL)
   {
      perror("Error: Cannot read file.\n");
   }

   return infile;
}

そしてそれを呼び出す

input = open_files(input);

または「参照渡し」を使用:

void open_files(FILE **infile, char *input[])
{
   *infile = fopen(input[1], "r");

   if (*infile == NULL)
   {
      perror("Error: Cannot read file.\n");
   }

   return *infile;
}

そしてそれを呼び出す

open_files(&input, in);

そうするだけinputで、呼び出し元のサイトに変数が実際に書き込まれます。

于 2013-06-03T23:16:29.140 に答える
0

を呼び出した後open_files(input, in);、ファイル ハンドルは にありませんinput

于 2013-06-03T23:21:27.847 に答える