2011-03-02 74 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