2014-10-06 117 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