Хобрук: Ваш путь к мастерству в программировании

как читать/записывать последовательность битов побитно в С++

Я реализовал алгоритм кодирования Хаффмана на C++, и он работает нормально. Я хочу создать алгоритм сжатия текста.

за каждым файлом или данными в цифровом мире стоит 0/1.

Я хочу сохранить в файле последовательность битов (0/1), сгенерированную алгоритмом кодирования Хаффмана.

моя цель - сохранить количество битов, используемых в файле для хранения. Я храню метаданные для декодирования в отдельном файле. Я хочу побитно записывать данные в файл, а затем читать то же самое побитно в С++.

проблема, с которой я сталкиваюсь в бинарном режиме, заключается в том, что он не позволяет мне помещать данные по крупицам. Я хочу поместить 10101 побитно в файл, но он помещает значения asci или 8 бит каждого символа за раз.

код

#include "iostream"
#include "fstream"
using namespace std;

int main(){
    ofstream f;
    f.open("./one.bin", ios::out | ios::binary);
    f<<"10101";
    f.close();

    return 0;
}

выход

введите здесь описание изображения

любая помощь или указатель на помощь приветствуются. благодарю вас.


  • Файлы (потоки) работают как минимум на уровне байтов. Невозможно поместить отдельные биты в файл. Вы должны собрать свои биты в байты и записать последние. 12.03.2021
  • @Scheff, значит, мне нужно создать буфер из 8 бит, а затем обработать их? 12.03.2021
  • Буфер 8 бит? Вы имеете в виду байт ака. char или unsigned char? 12.03.2021
  • Вам придется закодировать свой собственный механизм для записи в байты (это легко), но наименьший размер, который вы можете записать в файл, — это байт за раз. 12.03.2021
  • Я ожидаю, что вы сожмете в контейнер unsigned chars. Таким образом, может случиться так, что не все биты последнего байта используются. Однако нет возможности хранить части байта (ни в памяти, ни в файле). Вы должны помнить это в другом месте. (Обычно для неиспользуемых битов просто устанавливаются значения по умолчанию, например 0.) 12.03.2021
  • спасибо всем, я понял, мне просто нужно обработать крайние случаи с концепцией буфера. 12.03.2021
  • Для разработки, если вы не возражаете против пустой траты файлового пространства, вам может быть удобно (для отладки и диагностики) читать/записывать символы '0' и '1', а не выполнять побитовую буферизацию. 12.03.2021
  • спасибо @Scheff, я так и делаю, позаботься о крайних случаях. 12.03.2021
  • @Eljay, спасибо, но я хочу создать алгоритм сжатия текста для своего портфолио. 12.03.2021

Ответы:


1

Двоичный режим означает только то, что вы запросили, чтобы фактические байты, которые вы записываете, не были повреждены конечными преобразованиями строки. (Это проблема только в Windows. Ни в одной другой системе нет необходимости преднамеренно повреждать ваши данные.)

Вы все еще пишете байт за раз в двоичном режиме.

Чтобы записать биты, вы накапливаете их в целое число. Для удобства в беззнаковом целом. Это ваш битовый буфер. Вам нужно решить, накапливать ли их от наименьшего к большему или от наиболее к наименее значимым позициям. Как только вы накопите восемь или более битов, вы записываете один байт в свой файл и удаляете эти восемь битов из буфера.

Когда вы закончите, если в вашем буфере остались биты, вы записываете эти последние от одного до семи битов в один байт. Вам нужно тщательно продумать, как именно вы это делаете, и как узнать, сколько битов было, чтобы вы могли правильно декодировать биты на другом конце.

Накопление и извлечение выполняются с использованием битовых операций на вашем языке. В C++ (и многих других языках) это & (и), | (или), >> (правый сдвиг) и << (левый сдвиг).

Например, чтобы вставить один бит, x, в ваш буфер, а затем три бита в y, чтобы в итоге самые ранние биты оказались в наиболее значащих позициях:

unsigned buf = 0, bits = 0;

...

// some loop
{
   ...

   // write one bit (don't need the & if you know x is 0 or 1)
   buf = (buf << 1) | (x & 1);
   bits++;

   ...

   // write three bits
   buf = (buf << 3) | (y & 7);
   bits += 3;

   ...

   // write bytes from the buffer before it fills the integer length
   if (bits >= 8) {     // the if could be a while if expect 16 or more
       // out is an ostream -- must be in binary mode if on Windows
       bits -= 8;
       out.put(buf >> bits);
   }

   ...

}

...

// write any leftover bits (it is assumed here that bits is in 0..7 --
// if not, first repeat if or while from above to clear out bytes)
if (bits) {
    out.put(buf << (8 - bits));
    bits = 0;
}

...
12.03.2021
  • спасибо @Марк Адлер 12.03.2021
  • Новые материалы

    HMTL - Многозадачное обучение для решения задач НЛП
    Достижение результатов SOTA путем передачи знаний между задачами Область обработки естественного языка включает в себя десятки задач, среди которых машинный перевод, распознавание именованных..

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..