2014-11-03 131 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