2011-03-02 77 views
0

我们已经为系统编程分配了一个ASCII压缩项目,并且我在代码中遇到了一个特定的行。搞清楚在Unix中写入

我问了一个关于压缩的question,并且我在通过纸张上的示例文件的前十几个字母处理之后,将数组代码调整到了我的程序中。在ddd中,packed[]数组的值是我在纸上创建的值,但值不会写入文件。

unsigned char packed[7]; //compression storage 
    int i, jCount; 
    int j; 

    int bufferLength= sizeof(unpacked)/sizeof(char); 
    //loop through the buffer array 
    for (i=0; i< bufferLength-1; i++){ 
     j= i%7; 
     jCount++; 

     //fill up the compressed array 
     packed[i]= packer(unpacked[i], unpacked[i+1], j); 

     //compressed array is full, write to file, then clear 
     if ((j%7==6) && (j > 1)){ 
      int writeLoop; 
      for (writeLoop=0; writeLoop < 8; writeLoop++){ 
       //printf("%X", packed[writeLoop]); //write to screen 
       write(openWriteFile, &packed[writeLoop], 1);//this is my trouble, write to file 
      } 

      memset(&packed[0], 0, sizeof(packed)); //clear array 
     } 
//more code down here for padding the end of short bytes. 

写函数需要const void *作为第二个参数,这就是为什么我引用的是特定的阵列槽的值,但没有数据被写入到文件中。

当我删除&时,出现编译警告。

任何建议让我走下正确的道路,表示赞赏。

+0

对于初学者,'packed'只有7个字节,但是你的输出循环迭代8次。此外,你不应该需要一个循环; 'write(openWriteFile,packed,8)'应该可以工作。 – chrisaycock 2011-03-02 05:22:43

+0

如果系统调用看起来失败,检查返回值并且可能依次错误地返回是一个好主意。而对于系统编程家庭作业,这样做并持续报告可能会获得额外的分数。 – Keith 2011-03-02 05:32:21

+0

@ chrisaycock,根本没有变化。我有一个'write(openWriteFile,&fileSize,4)'声明来将原始文件大小写入压缩文件,并且它将'int fileSize'完全写入文件。 @Keith,当我打开写入文件时,它会以适当的权限创建,因为rw显示在'ls -l'输出中。我有内置的错误处理,但错误只显示为负数,'writeOpenFile'是一个正整数。 – Jason 2011-03-02 05:36:12

回答

0

我认为应该是packed[j] = ...而不是packed[i]。正如chrisaycock所指出的那样,你可以写出整个包装数组,你不需要循环:write(openWriteFile, packed, sizeof packed);你应该避免所有这些文字......你有3个7个实例,8个实例和6个实例,当你应该有一个单一的定义常数,并适当地使用+或 - 1。此外jCount未初始化。

编辑: 这里是没有这些问题的一些代码:

#define PACKEDSIZE 7 // Why 7? 

    unsigned char packed[PACKEDSIZE]; //compression storage 
    int i, jCount = 0; 
    int j = 0; 

    int bufferLength = sizeof(unpacked)/* /sizeof(char) ... not needed because sizeof(char) is 1 in all conforming implementations */; 
    //loop through the buffer array 
    for(i = 0; i < bufferLength-1; i++){ 
     jCount++; 

     //fill up the compressed array 
     packed[j]= packer(unpacked[i], unpacked[i+1], j); 

     if(++j == sizeof packed){ 
      if(write(openWriteFile, packed, sizeof packed) != sizeof packed) 
       reportWriteError(); // stub -- do real error handling here 
      //memset(packed 0, sizeof packed); // this isn't necessary 
      j = 0; 
     } 
    } 
+0

啊,很好!写入缓冲区时,OP应该将'j'重置为0,而不是依赖于mod操作。 – chrisaycock 2011-03-02 05:27:49

+0

我试过了你的建议,但结果没有改变,因为在写入文件头之后文件大小显示为4个字节。至于为什么7打包,当我使用一个8字节输入数组到7字节输出时,理解位移是比较容易的。 – Jason 2011-03-02 05:49:39

+0

@Jason然后你做了其他的错误......这段代码甚至被执行了吗?以及如何定义解包?顺便说一句,sizeof(char)总是1,所以你不需要这个分歧。 – 2011-03-02 05:51:29

1

您正在阅读过去的数组的末尾。您声明packed[7],然后在您的写入循环中访问元素0到7(8个元素)。

通常,您可以使用write来编写一系列字节,而不仅仅是一个字节。在您的情况,它表示与

write(openWriteFile, packed, 8); 

更换

int writeLoop; 
    for (writeLoop=0; writeLoop < 8; writeLoop++){ 
     write(openWriteFile, &packed[writeLoop], 1); 
    } 

,并改变你的声明

unsigned char packed[8]; //compression storage 

或者,也许它应该是一个7字节写?在这种情况下用7s替换8s。

+0

我工作的印象是写一个数组的内容,每个元素都需要一个循环。你是说它不是真的吗?另外,它是一个7字节的写入,而不是8,因为我将8个字节缩减为7. – Jason 2011-03-02 05:34:21

+0

@Jason不,这是不正确的 - 写入有一个论点,说明要写入多少字节。而你的writeLoop = 0; writeLoop <8迭代8次,而不是7. – 2011-03-02 05:41:55

+0

@Jason:每个字节的循环位于write()函数中。 – 2011-03-02 13:51:01