2014-11-03 133 views
2

我正在寫一個使用霍夫曼算法來壓縮文本文件的程序。我已經通過將打印ASCII字符打印到文件來測試我的程序,並且它工作正常。但是,現在我必須實現使用位,我的程序不起作用。看起來好像我沒有閱讀或寫出正確的位。 這是我測試的結果: 在輸入文件中,我把abc的輸入文件壓縮。然後我解壓縮出來的是aaa。 下面是我如何讀取和寫入位的片段讀取和寫入文件C++

class BitInput { 
    istream& in; // the istream to delegate to 
    char buf;  // the buffer of bits 
    int nbits;  // the bit buffer index 

public: 

BitInputStream(istream& s) : in(s), buf(0), bufi(8) { } 
~BitInputStream //destructor 
{ 
    delete in; 
}; 

/** Read the next bit from the bit buffer. 
* Return the bit read as the least significant bit of an int. 
*/ 
int readBit(){ 
    int i; 
    if(nbits == 8){ 
     buf = in.get(); 
     nbits = 0; 
    } 
    i = (1 & buf>>(7-nbits)); //This could be the problem, I'm not getting the writing bit 
    nbits++; 
    return i; 
} 

/** Read a char from the ostream (which is a byte)*/ 
int readChar(){ 
    int sum = 0; 
    for(int i = 7; i>=0; i--) 
     sum = (sum*2) + readBit(); 
    return sum; 
} 

class BitOutput { 
    ostream& out; // the istream to delegate to 
    char buf;  // the buffer of bits 
    int nbits;  // the bit buffer index 

public: 

    BitOutput(istream& s) : in(s), buf(0), bufi(8) { } 

    /* Write the least significant bit of the argument */ 
    void writeBit(int i){ 
     //Flush the buffer 
     if(nbits == 8){ 
      out.put(buf); 
      out.flush(); 
      nbits = 0; 
      buf = 0; 
     } 
     buf = buf | (i<<(7-nbits)); //Did it write the right bit to ostream ? 
     nbits++; 
    } 

    /** Write a char to the ostream (a byte) */ 
    void writeChar(int ch){ 
     for(int i = 7; i >= 0; i--) 
      writeBit((ch >> i) & 1); 
    } 
+0

我們需要看到BitOutput的析構函數。那裏有一個很好的機會。 – 2014-11-03 07:50:43

+0

哎呀,我忘了把我放在參數。我編輯了我的代碼 – 2014-11-03 07:54:58

+0

如果使用32位緩衝區並且寫出字節,這意味着最多7位可以保留在緩衝區中,因此無需特殊邏輯即可將高達25位的代碼字寫入緩衝區。 – harold 2014-11-03 10:24:23

回答

0
/* Write the least significant bit of the argument */ 
void writeBit(){ 
    int i; // <-- HERE 
    //Flush the buffer 
    if(nbits == 8){ 
    out.put(buf); 
    out.flush(); 
    bufi = 0; 
    buf = 0; 
    } 
buf = buf | (i<<(7-nbits)); //Did it write the right bit to ostream ? 
nbits++; 
} 

你永遠不分配i任何合理的值。所以當你轉移它時,你正在轉移垃圾。

你可能想:

/* Write the least significant bit of the argument */ 
void writeBit(int i){ 
    //Flush the buffer 
    if(nbits == 8){ 
    out.put(buf); 
    out.flush(); 
    bufi = 0; 
    buf = 0; 
    } 
buf = buf | (i<<(7-nbits)); //Did it write the right bit to ostream ? 
nbits++; 
} 

此外,我們展示BitOutput的析構函數。這裏也有一個很好的機會。

+0

實際上我沒有寫析構函數,因爲我在堆棧中聲明它 – 2014-11-03 07:56:56

+0

我還讀寫字節嗎? – 2014-11-03 08:00:04

+0

@JoeCool你需要編寫一個析構函數。否則,你並不總是寫最後幾位。 – 2014-11-03 08:49:22

0

您的代碼:

//Flush the buffer 

    if(nbits == 8){ 
     out.put(buf); 
     out.flush(); 
     bufi = 0; 
     buf = 0; 
    } 

不會重置和nbits爲0

+0

固定,但它仍然無法正常工作 – 2014-11-03 14:36:13