2014-10-06 91 views
1

我正在为一个类的C++文本文件压缩程序工作。 我有一切工作,除了能够以二进制模式输出到文件。 我使用:二进制输出C++

FILE* pFile; 
pFile = fopen(c, "wb"); 

为了打开文件以二进制方式写,

bool Buffer[8] = { 0, 0, 0,0, 0,0, 0,0 }; 

进出口使用的bool的缓冲区(初始化为全0)来存储1和0至存储每个字节的数据,直到我使用fwrite。

vector<bool> temp2 = bitstring[temp];//bitstring refers to a vector in a map at key [temp] 
for (vector<bool>::iterator v = temp2.begin(); v != temp2.end(); ++v) 
     { 

      if (j < 8)//To create an 8 bit/byte buffer 
      { 
       if (*v == 1)//Checks the vector at that position to know what the bit is. 
        Buffer[j] =1;//sets the array at 'j' to 1 
       else 
        Buffer[j] =0 ;//sets the array at 'j' to 0 

       j++; 
      } 
      else //once the Buffer hits 8 it will print the buffer to the file 
      { 

       fwrite(Buffer,1,sizeof(Buffer), pFile); 

       clearBuffer(Buffer);//Clears the buffer to restart the process. 
       j = 0; 

      } 

     } 

的(矢量迭代器)正在经历被分配给一个特定的字符,基本上表示所述字符的唯一二进制串的bool的向量。我的问题是,不是在缓冲区中输出为二进制文件,而是在二进制模式下输出本质上的ASCII字符,而不是将数字输出为二进制。最终导致文件的大小超过了它的需求。我怎么能改变缓冲区,只是输出位。我被告知使用按位运算符,但我无法找到有关在C++中实现这一点的非常多文档。任何帮助表示赞赏,并

+0

'的std :: vector的 '并不涉及连续的位序列。 ['std :: bitset <>'](http://en.cppreference.com/w/cpp/utility/bitset)确实有用,但可能不适合您的用例,因为它不支持可变长度比特流。 – 2014-10-06 19:47:05

+0

注意:你有一个逻辑错误,使用:for(...){if(index == buffer_size {write_buffer(); index = 0;} insert_into_buffer();} write_buffer_if_index_is_not_zero; – 2014-10-06 19:58:45

+0

注意:std :: vector 可能首先是错误的选择 – 2014-10-06 20:16:03

回答

1

我会首先使用std::bitset,绝对灵活为此

std::bitset<8> BufferBits; 
vector<bool> temp2 = bitstring[temp];//bitstring refers to a vector in a map at key [temp] 
for (vector<bool>::iterator v = temp2.begin(); v != temp2.end(); ++v) 
     { 

      if (j < 8)//To create an 8 bit/byte buffer 
      { 
       if (*v == 1)//Checks the vector at that position to know what the bit is. 
        BufferBits[j] =1;//sets the array at 'j' to 1 
       else 
        BufferBits[j] =0 ;//sets the array at 'j' to 0 

       j++; 
      } 
      else //once the Buffer hits 8 it will print the buffer to the file 
      { 
       unsigned long i = BufferBits.to_ulong(); 
       unsigned char c = static_cast<unsigned char>(i); 
       fwrite(&c, sizeof(char), 1, pFile); 

       BufferBits.reset();//Clears the buffer to restart the process. 
       j = 0; 

      } 

     } 

注:我只是认为在关于你的位向量的问题

+0

完美工作,从260KB文件下降到127KB。感谢BUNCH!@ marco-a。 – eragon2262 2014-10-06 20:47:14

+0

@ eragon2262很高兴我帮助过了。不要忘记将此标记为公认的答案if它解决了你的问题:) – 2014-10-06 20:48:27

0

要在一个字节中设置一个位,使用shift和an。当j为0时,此代码以字节中的最高位开始,这是惯例。

char data = 0; 
// ... 
data |= 0x80 >> j; 
0

要在字节设置各个位,你可以使用一个联盟与位域:

typedef union 
{ 
    struct 
    { 
    unsigned char value; 
    } byte; 
    struct 
    { 
    unsigned char b0:1; 
    unsigned char b1:1; 
    unsigned char b2:1; 
    unsigned char b3:1; 
    unsigned char b4:1; 
    unsigned char b5:1; 
    unsigned char b6:1; 
    unsigned char b7:1; 
    } bits; 
} u; 

int main() 
{ 
    u buffer = {{0}}; 

    buffer.bits.b0 = 1; 
    buffer.bits.b1 = 0; 
    buffer.bits.b2 = 1; 

    cout << static_cast<int>(buffer.byte.value) << endl; 
    return 0; 
} 

这将打印出5(取决于您的PC的字节序)

+1

我想发布一个位域答案,但意识到位域不容易解决。 – 2014-10-06 20:27:38

+0

是的,他们有时候有点狡猾,但我认为在他的特殊情况下可能会有所帮助。我个人尽量避免使用它们。 – 2014-10-07 05:01:10