Question

if i am writing into file with fwrite as follows

char buffer[3]={255,255,255,'\0'};
char buffer2[3]={0,0,0,'\0'};

fwrite(buffer, sizeof(char), sizeof(buffer), outputFile);
fwrite(buffer2, sizeof(char), sizeof(buffer2), outputFile);

what i am trying to understand is the third argument, sizeof(buffer)

my issue is that if the array has an appended '\0' nul character, does fwrite copy the nul character also into the file

also if i used a while loop to write into a file such as

 int i=0;

    while(i++<100){

     fwrite(buffer, sizeof(char), sizeof(buffer), outputFile);
     fwrite(buffer2, sizeof(char), sizeof(buffer2), outputFile);

    }

what are the potential problems here directly to do with the nul character

also one more question , as i am having a problem with my program

int main (int argc, char *argv[]) {

   // check that the types have the size i'm relying on here
   assert (sizeof(bits8)  == 1);
   assert (sizeof(bits16) == 2);
   assert (sizeof(bits32) == 4);

   FILE *outputFile;
   int squareSize;

   outputFile = fopen(BMP_FILE, "wb");
   assert ((outputFile!=NULL) && "Cannot open file");

   writeHeader(outputFile);

   printf ("Enter square size (must be a factor of %d): \n", SIZE);
   scanf ("%d", &squareSize);
   assert (SIZE % squareSize == 0);


   char buffer[squareSize*BYTES_PER_PIXEL]; //white
   char buffer2[squareSize*BYTES_PER_PIXEL]; //black

   initialize(buffer, buffer2, squareSize);

   int line=0;
   int m=1;

      while(line<SIZE){

         if(line%squareSize==0&&m==1)
            m=0;
         else if(line%squareSize==1&&m==0)
            m=1;

         writeToFile(buffer,buffer2,m,outputFile,squareSize);

         line+=squareSize;

         printf("\nline is %d inside while loop ",line);

      }

   fclose(outputFile);

   return EXIT_SUCCESS;
}

void writeHeader (FILE *file) {
   assert(sizeof (bits8) == 1);
   assert(sizeof (bits16) == 2);
   assert(sizeof (bits32) == 4);

   bits16 magicNumber = MAGIC_NUMBER;
   fwrite (&magicNumber, sizeof magicNumber, 1, file);

   bits32 fileSize = OFFSET + (SIZE * SIZE * BYTES_PER_PIXEL);
   fwrite (&fileSize, sizeof fileSize, 1, file);

   bits32 reserved = 0;
   fwrite (&reserved, sizeof reserved, 1, file);

   bits32 offset = OFFSET;
   fwrite (&offset, sizeof offset, 1, file);

   bits32 dibHeaderSize = DIB_HEADER_SIZE;
   fwrite (&dibHeaderSize, sizeof dibHeaderSize, 1, file);

   bits32 width = SIZE;
   fwrite (&width, sizeof width, 1, file);

   bits32 height = SIZE;
   fwrite (&height, sizeof height, 1, file);

   bits16 planes = NUMBER_PLANES;
   fwrite (&planes, sizeof planes, 1, file);

   bits16 bitsPerPixel = BITS_PER_PIXEL;
   fwrite (&bitsPerPixel, sizeof bitsPerPixel, 1, file);

   bits32 compression = NO_COMPRESSION;
   fwrite (&compression, sizeof compression, 1, file);

   bits32 imageSize = (SIZE * SIZE * BYTES_PER_PIXEL);
   fwrite (&imageSize, sizeof imageSize, 1, file);

   bits32 hResolution = PIX_PER_METRE;
   fwrite (&hResolution, sizeof hResolution, 1, file);

   bits32 vResolution = PIX_PER_METRE;
   fwrite (&vResolution, sizeof vResolution, 1, file);

   bits32 numColors = NUM_COLORS;
   fwrite (&numColors, sizeof numColors, 1, file);

   bits32 importantColors = NUM_COLORS;
   fwrite (&importantColors, sizeof importantColors, 1, file);

}
void initialize(char *buffer, char*buffer2, int size){

   //white for buffer 255,255,255 1 pixel
   //black for buffer2 00,00,00 1 pixel

   int buf = 255;
   int buf2 = 0;
   int i = 0;

   while(i<size*3){
      buffer[i]=buf;
      buffer2[i]=buf2;

      printf("\nbuffer 1 [i] is %c and i is %d\n",buffer[i],i);
      printf("buffer 2 [i] is %c and i is %d\n",buffer2[i],i);

      i++;

     // printf("\nline ran %d times inside initialize loop ",i);
   }


   buffer[i]='\0';
   buffer2[i]='\0';

   printf("%s\n",buffer);
   printf("%s",buffer2);

}
void writeToFile(char *buffer,char *buffer2, int m, FILE *file,
int squareSize){

int k = 0;



           // printf("\nline ran %d times",line);

               if(m==0){
                  while(k<(SIZE/squareSize)){
                     fwrite(buffer2, sizeof(char), sizeof(buffer2), file);
                     k+=1;
                     fwrite(buffer, sizeof(char), sizeof(buffer), file);
                     k+=1;

                   //  printf("\nline ran %d times inside first if ",line);

                    }                  
                } 
               else if(m==1){
                  while(k<(SIZE/squareSize)){
                     fwrite(buffer, sizeof(char), sizeof(buffer), file);
                     k+=1;
                     fwrite(buffer2, sizeof(char), sizeof(buffer2), file);
                     k+=1;

                   //  printf("\nline ran %d times inside second else if",line);

                    }

                }



}

the program is supposed to write to a file that is supposed to be a bmp file

the header write output function works fine

however i am having problem with the function initialize and the function writeToFile which i think has to do witht he nul pointer because i think fwrite is taking the nul pointer over as well and causing the bmp file to have the wrong information throw into it , also if i do remove teh nul character does fwrite produce problems by not stopping at the specified spot or does it stil copy correctly

i dont know what the problem is but the program is not writing in the order that i imagined i have been at it ALL NIGHT and it still does not function correctly i am not sure where the problem is

the program is supposed to write into a 512 by 512 output file which is supposed to print out checkered black and white squares based on the input by user of a square which is a factor of 512

so that if the person chooses the input to be 256 , the program is supposed to divide the 512 by 512 space into 4 square with the first square being black then white, then white then black and etc

if the person choose 16 as the size of square in pixels, then i am supposed to divide the space into squares of 16 pixels sides ion the order of starting with black then white(across) next line above white then black all the way to the end

i think the problem is with my write to File function but i am not sure what the problem is, really confusing

hope you can help to give me some suggestions on how to deal with this problem

any help would be highly appreciated so that i can get this over and done with

Was it helpful?

Solution

The second argument of fwrite() is the size of each object, and the third argument is the number of objects. In your case, you tell it to write 4 objects of size 1, but here you could just write one object of size 4 just as easily.

"Nul characters" are irrelevant here, since they terminate strings, and fwrite() explicitly deals with binary objects, not strings. It'll write exactly what you give it to the file.

As an aside, a regular unqualified char can be (and often is) signed, rather than unsigned, so trying to stuff all those 255s into them may not be wise. unsigned char may be better for this.

In the writeToFile() function in your third block of code, this:

fwrite(buffer, sizeof(char), sizeof(buffer), file);

is a simple misunderstanding of how the sizeof operator works. In this context, buffer is not an array, it's a pointer to char that you have passed to the function. sizeof will therefore give you the size of a character pointer, usually 4 or 8 bytes, and that size will obviously be totally unrelated to the size of the buffer it points to. If char pointers are 8 bytes on your system, then sizeof(buffer) in this context will always evaluate to 8, regardless of whether you initially set up a 3 byte array, or a 4 byte array, or a 672 byte array.

To make what you want to do work in a function like this, you'll have to explicitly pass to the writeToFile() function the size of the buffer you created, and use that instead of sizeof.

OTHER TIPS

fwrite and fread don't care at all about zero bytes. They simply write or read the number of bytes you ask for.

And note that buffer2 does not just have a '\0' appended but is in fact all '\0's since 0 and '\0' are identical in that context.

You don't need to zero-terminate your buffers since they aren't strings, they're just data and can contain zero-bytes within them.

Question: does fwrite copy the nul character also into the file?

Answer: The way you are calling it, the answer is "Yes". The third argument to the buffer is the number of objects that you wish to write to the stream.

Solution to your problem

You can change your variables

char buffer[3]={255,255,255,'\0'}; // This should be a compiler error/warning.
char buffer2[3]={0,0,0,'\0'};      // You have 4 items in {} for an array of size 3.

to

char buffer[3]={255,255,255};
char buffer2[3]={0,0,0};

You need a '\0' at the end of an array of char only if you want to treat the array as a null-terminated string. Since you are using the array to store only pixel values, you don't need to have the terminating null character in your array.

Potential pitfalls of not having the null character is that most functions that work with strings expect a terminating null character. They won't work with buffer or buffer2. Don't use:

  1. Any of the standard string manipulation functions, such as strlen, strcpy.
  2. printf("%s", buffer);.
  3. and many other functions.

Considering your usage of those variable, I don't think you need to use them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top