1

I am trying to write my 2D character array "A" into a .txt file "some_file.txt". I tried to use the Sergey Kalinichenko's answer from this question for my code (see below). However, it does not work. Could you please tell me what I am doing wrong.

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


char A[10][10] =
{
  {'~', 'S', 'S', 'S', 'S', 'S', '~', '~', '~', 'S'},
  {'S', '~', '~', '~', '~', '~', '~', '~', '~', 'S'},
  {'S', '~', '~', 'S', 'S', 'S', '~', 'S', '~', '~'},
  {'S', '~', '~', '~', '~', '~', '~', 'S', '~', '~'},
  {'S', '~', 'S', 'S', 'S', '~', '~', '~', '~', '~'},
  {'~', 'S', '~', '~', '~', '~', '~', '~', '~', '~'},
  {'~', 'S', '~', '~', '~', '~', 'S', '~', '~', '~'},
  {'~', 'S', '~', '~', '~', '~', 'S', '~', '~', 'S'},
  {'~', 'S', '~', 'S', 'S', '~', '~', '~', '~', 'S'},
  {'~', '~', '~', '~', '~', '~', '~', '~', '~', 'S'}
};

void saveImage(int height, int width, char image[height][width], const char* file_name)
{
  FILE *file = fopen(file_name, "wb");
  fwrite(image, sizeof(char), sizeof(image), file);
  fclose(file);
}

int main()
{
  saveImage(10, 10, A, "some_file.txt");

  return 0;
}
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
3nondatur
  • 353
  • 2
  • 9

2 Answers2

4

When sending an array to a function as a parameter, the array decays into a pointer. This post may be a good reading start on the decay.

Because of this decay, your sizeof(image) is actually the size of the pointer and not the number of all array elements. As you already saw, you need to replace it with the actual element number:

fwrite(image, sizeof(char), height*width, file);

The important part is that when compiling, you should get a warning indicating the above. For instance, on GCC 9.4.0 (Ubuntu) I get:

cscratch.c: In function ‘saveImage’:
cscratch.c:23:35: warning: ‘sizeof’ on array function parameter ‘image’ will return size of ‘char (*)[(sizetype)(width)]’ [-Wsizeof-array-argument]
   23 | fwrite(image, sizeof(char), sizeof(image), file);
      |                                   ^
cscratch.c:19:44: note: declared here
   19 | void saveImage(int height, int width, char image[height][width], const char* file_name)


  |                                       ~~~~~^~~~~~~~~~~~~~~~~~~~

As part of a basic compilation that does not have any special warning flags specified (it is highly recommended to use stricter and more comprehensive warning flags than the default ones).

In this message, you can clearly see the issue and its source - point being that one should enable strict warnings and pay close attention to them.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
atru
  • 4,699
  • 2
  • 18
  • 19
0

sizeof in your question is giving the size of the pointer. Use a pointer to the array and sizeof will work fine :). Also, use the correct types.

void saveImage(size_t height, size_t width, char (*image)[height][width], const char* file_name)
{
  FILE *file = fopen(file_name, "wb");
  if(file) 
  {
     fwrite(image, sizeof(char), sizeof(*image), file);
     fclose(file);
  }
}

//usage saveImage(10, 10, &A, "some_file.txt");

or

void saveImage(size_t height, size_t width, char (*image)[width], const char* file_name)
{
  FILE *file = fopen(file_name, "wb");
  if(file) 
  {
     fwrite(image, sizeof(char), height * sizeof(*image), file);
     fclose(file);
  }
}

//usage   saveImage(10, 10, A, "some_file.txt");

0___________
  • 60,014
  • 4
  • 34
  • 74