2011-02-01 60 views
6

我正在编写一个压缩程序,并且需要使用C++将位数据写入二进制文件。如果任何人可以在撰写声明或有建议的网站上提供建议,我将非常感激。将位数据输出到二进制文件C++

道歉,如果这是一个简单或令人困惑的问题,我很努力地在网上找到答案。

回答

3

将这些位收集到整个字节中,例如unsigned char或std :: bitset(其中bitset大小是CHAR_BIT的倍数),然后一次写入整个字节。计算机“处理位”,但可用的抽象 - 特别是IO - 是作为程序员处理单个字节。按位操作可用于切换特定位,但您始终处理字节大小的对象。

在输出结束时,如果你没有一个完整的字节,你需要决定如何存储。 iostream和stdio都可以分别使用ostream :: write和fwrite写入未格式化的数据。

8>(8是CHAR_BIT最常见的值),您可以考虑使用更大的块大小,例如4-32或更多字符的数组或等价物大小的位集。

+0

谢谢弗雷德你的建议,这给了我上哪里找一个手柄。 – 2011-02-01 11:39:14

2

对于编写二进制文件,我发现最有用的技巧是将所有二进制文件作为单个数组存储在内存中,然后将其全部移到硬盘上。一次执行一次,或一次执行一个字节,或一次执行一个无符号长整型,不如将所有数据存储在数组中并使用一个“fwrite()”实例将其存储到硬盘。

size_t fwrite(const void * ptr,size_t size,size_t count,FILE * stream);

价:http://www.cplusplus.com/reference/clibrary/cstdio/fwrite/

在英国:

的fwrite([数组*存储的数据的],[尺寸数组对象的字节无符号字符 - > 1,为无符号长多头 - > 8 ],[阵列中的实例数],[文件*])

总是检查您的返回验证成功!

另外,可以使参数具有尽可能大的对象类型是最快的方法([unsigned long long]> [char])。虽然我不熟悉“fwrite()”背后的编码,但我认为从代码中使用的自然对象转换为[unsigned long long]的时间与写入相比需要更多时间,而不是“fwrite() “充分利用你所拥有的东西。

回到我学习Huffman编码时,花了几个小时才知道[char]和[unsigned char]之间有区别。注意这个方法,你应该总是使用无符号变量来存储纯二进制文件。

1

通过下面类,你可以写和读的点点滴滴

class bitChar{ 
public: 
    unsigned char* c; 
    int shift_count; 
    string BITS; 

    bitChar() 
    { 
     shift_count = 0; 
     c = (unsigned char*)calloc(1, sizeof(char)); 
    } 

    string readByBits(ifstream& inf) 
    { 
     string s =""; 
     char buffer[1]; 
     while (inf.read (buffer, 1)) 
     { 
      s += getBits(*buffer); 
     } 
     return s; 
    } 

    void setBITS(string X) 
    { 
     BITS = X; 
    } 

    int insertBits(ofstream& outf) 
    { 
     int total = 0; 

     while(BITS.length()) 
     { 
      if(BITS[0] == '1') 
       *c |= 1; 
      *c <<= 1; 
      ++shift_count; 
      ++total; 
      BITS.erase(0, 1); 

      if(shift_count == 7) 
      { 
       if(BITS.size()>0) 
       { 
        if(BITS[0] == '1') 
         *c |= 1; 
        ++total; 
        BITS.erase(0, 1); 
       } 

       writeBits(outf); 
       shift_count = 0; 
       free(c); 
       c = (unsigned char*)calloc(1, sizeof(char)); 
      } 
     } 

     if(shift_count > 0) 
     { 
      *c <<= (7 - shift_count); 
      writeBits(outf); 
      free(c); 
      c = (unsigned char*)calloc(1, sizeof(char)); 
     } 
     outf.close(); 
     return total; 
    } 

    string getBits(unsigned char X) 
    { 
     stringstream itoa; 
     for(unsigned s = 7; s > 0 ; s--) 
     { 
      itoa << ((X >> s) & 1); 
     } 

     itoa << (X&1) ; 
     return itoa.str(); 
    } 

    void writeBits(ofstream& outf) 
    { 
     outf << *c; 
    } 

    ~bitChar() 
    { 
     if(c) 
      free(c); 
    } 
}; 

example

#include <iostream> 
#include <sstream> 
#include <fstream> 
#include <string> 
#include <stdlib.h> 
using namespace std; 


int main() 
{ 
    ofstream outf("Sample.dat"); 
    ifstream inf("Sample.dat"); 

    string enCoded = "101000001010101010"; 

    //write to file 
    cout << enCoded << endl ; //print 101000001010101010 
    bitChar bchar; 
    bchar.setBITS(enCoded); 
    bchar.insertBits(outf); 

    //read from file 
    string decoded =bchar.readByBits(inf); 
    cout << decoded << endl ; //print 101000001010101010000000 
    return 0; 
}