fwrite并打印到输出文件程序中

时间:2014-04-24 03:18:43

标签: c pointers fwrite

如果我用fwrite写入文件如下

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);

我想要了解的是第三个参数,sizeof(缓冲区)

我的问题是如果数组有一个附加的'\ 0'nul字符,那么fwrite也会将nul字符复制到文件中

如果我使用while循环写入文件,如

 int i=0;

    while(i++<100){

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

    }

这里与nul角色直接相关的潜在问题是什么

还有一个问题,因为我的程序存在问题

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);

                    }

                }



}

该程序应该写入一个应该是bmp文件的文件

标头写输出功能正常

然而我有函数初始化和函数writeToFile的问题,我认为它与nul指针有关,因为我认为fwrite也将nul指针放在上面并导致bmp文件有错误的信息投入它,如果我删除teh nul字符,fwrite不会在指定的位置停止产生问题或者是否正确复制

我不知道问题是什么,但程序没有按照我想象的顺序编写 我一直都在它,它仍然无法正常工作我不知道问题出在哪里

该程序应该写入一个512×512的输出文件,该文件应该根据用户输入的方格打印出方格的黑白方块,这是一个512的因子

因此,如果该人选择输入为256,程序应该将512乘512空间划分为4平方,第一个方块是黑色然后是白色,然后是白色然后是黑色等等

如果人选择16作为像素的正方形大小,那么我应该将空间划分为16像素边的正方形离子以黑色开始的顺序然后白色(穿过)下一行上面的白色然后黑色全部到最后的方式

我认为问题在于我对文件功能的写入,但我不确定问题是什么,真的很混乱

希望你能帮忙给我一些关于如何处理这个问题的建议

任何帮助都将受到高度赞赏,以便我可以完成这项任务并完成

3 个答案:

答案 0 :(得分:1)

fwrite()的第二个参数是每个对象的大小,第三个参数是对象的数量。在您的情况下,您告诉它编写4个大小为1的对象,但在这里您可以轻松地编写一个大小为4的对象。

&#34; Nul字符&#34;这里是无关紧要的,因为它们终止字符串,而fwrite()显式处理二进制对象,而不是字符串。它会准确地写出你将它提供给文件的内容。

顺便说一句,常规的不合格char可以(通常是)签名,而不是签名,因此尝试将所有255填入其中可能并不明智。 unsigned char可能会更好。

在第三个代码块的writeToFile()函数中,这个:

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

是对sizeof运算符如何工作的简单误解。在此上下文中,buffer不是数组,它是您传递给函数的char指针。因此,sizeof将为您提供字符指针的大小,通常为4或8个字节,并且该大小显然与它指向的缓冲区大小完全无关。如果char指针在您的系统上是8个字节,则无论您最初是设置3字节数组还是4字节数组,此上下文中的sizeof(buffer)将始终求值为8 ,或一个672字节的数组。

要在这样的函数中使你想要做的工作,你必须明确地传递给你创建的缓冲区大小的writeToFile()函数,并使用它来代替{{1 }}

答案 1 :(得分:1)

问题:是否会将nul字符复制到文件中?

答案:你打电话的方式,答案是&#34;是&#34;。缓冲区的第三个参数是您希望写入流的对象数。

解决您的问题

您可以更改变量

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.

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

只有在您希望将数组视为以null结尾的字符串时,才需要'\0'数组末尾的char。由于您使用数组仅存储像素值,因此您不需要在数组中使用终止空字符。

没有空字符的潜在缺陷是大多数使用字符串的函数都需要终止空字符。他们无法与bufferbuffer2合作。不要使用:

  1. 任何标准字符串操作函数,例如strlenstrcpy
  2. printf("%s", buffer);
  3. 和许多其他功能。
  4. 考虑到您对这些变量的使用,我认为您不需要使用它们。

答案 2 :(得分:1)

fwritefread并不关心零字节。它们只是写或读你要求的字节数。

请注意,buffer2不仅附加了'\0',而且实际上所有'\0'都是0,因为'\0'和{{1}}在此相同

您不需要将缓冲区归零,因为它们不是字符串,它们只是数据,并且可以包含零字节。