2014-10-06 4 views
1

Я работаю над программой сжатия текстового файла на C++ для класса. У меня все работает, кроме возможности выводить файл в двоичном режиме. Я использую:Binary Output C++

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

Для того, чтобы открыть файл для записи в двоичном режиме,

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

Im использованием буфера BOOLS (инициализируется все 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; 

      } 

     } 

(вектор итератора) происходит через вектор BOOLS, который назначается на определенный характер, по существу уникальный двоичную строку, которая представляет символ. Моя проблема заключается в том, что вместо вывода в виде двоичного кода в буфере его вывод по существу ASCII-символов в двоичном режиме, а не только цифры как двоичные. Который в конечном итоге делает файл WAY больше, чем он должен быть. Как я могу изменить буфер, чтобы только вывести бит. Мне сказали использовать побитовые операторы, но я не могу найти очень много документации по реализации этого в C++. Любая помощь приветствуется, и

+0

'станд :: вектор 'не адресует последовательную последовательность бит. ['std :: bitset <>'] (http://en.cppreference.com/w/cpp/utility/bitset), но может быть непригоден для вашего варианта использования, поскольку он не поддерживает потоки битов переменной длины. –

+0

Примечание: у вас есть логическая ошибка: используйте для: (...) {if (index == buffer_size {write_buffer(); index = 0;} insert_into_buffer();} write_buffer_if_index_is_not_zero; –

+0

Примечание: std :: vector может быть неправильным выбором, в первую очередь. –

ответ

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

Работал отлично, упал с файла 260 КБ до 127 КБ. спасибо BUNCH! @ marco-a. – eragon2262

+0

@ eragon2262 Рад, что я помог. Не забудьте отметить это как принятый ответ, если он решил вашу проблему :) –

0

Для установите один бит в байте, используйте shift и a или. Этот код начинается с бита самого высокого порядка в байте, когда 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 (в зависимости от байтов вашего компьютера)

+1

Я думал о публикации ответа в битполе, но понял, что битполы нелегко адресовать. –

+0

Да, они немного изворотливы, чтобы иногда использовать, но я думал, что в его конкретном случае, возможно, это может помочь. лично я стараюсь избегать их использования. –