У меня есть программа, которая создает дерево Хаффмана на основе частоты символов ASCII, считываемой в текстовом файле ввода. Коды Хаффмана хранятся в строковом массиве из 256 элементов, пустая строка, если символ не читается. Затем эта программа также кодирует и сжимает выходной файл, а затем может принять сжатый файл в качестве входного файла и выполняет распаковку и декодирование.
Таким образом, моя программа принимает входной файл, сжимает и кодирует выходной файл, закрывает выходной файл и открывает кодировку в качестве входного файла и принимает новый выходной файл, который должен иметь декодированное сообщение, идентичное исходному файл ввода текста.
Моя текущая проблема с этой программой: при декодировании сжатого файла я получаю дополнительный символ или около того, который не декодирован в исходном входном файле. Это связано с мусорными битами из того, что я знаю. В ходе исследований я обнаружил, что одним из решений может быть использование символа psuedo-EOF для прекращения декодирования до считывания битов мусора, но я не уверен, как реализовать это в моих текущих функциях, которые обрабатывают кодирование и декодирование, поэтому все рекомендации и помощь очень ценятся ,
Моя конечная цель - иметь возможность использовать эту программу для полного декодирования закодированного файла без мусорных битов, отправляемых в выходной файл.
Ниже у меня есть две функции, encodedOutput и decodeOutput, которые обрабатывают сжатие и распаковку.
(Для функции encodedOutput fileName - это параметр входного файла, fileName2 - параметр выходного файла)
(Для функции decodeOutput fileName2 - параметр входного файла, fileName 3 - параметр выходного файла)
код [256] является параметром для обеих этих функций и содержит код Хаффмана для каждого уникального символа, считываемого в исходном входном файле, например, символ «Н», читаемый во входном файле, может иметь код «111» хранится в массиве кода для кода [72] во время его передачи функциям.
freq [256] содержит частоту чтения каждого символа ascii или 0, если он отсутствует в исходном входном файле.
void encodeOutput(const string & fileName, const string & fileName2, string code[256]) {
ifstream ifile; //to read file
ifile.open(fileName, ios::binary);
if (!ifile)//to check if file is open or not
{
die("Can't read again"); // function that exits program if can't open
}
ofstream ofile;
ofile.open(fileName2, ios::binary);
if (!ofile) {
die("Can't open encoding output file");
}
int read;
read = ifile.get(); //read one char from file and store it in int
char buffer = 0, bit_count = 0;
while (read != -1) {//run this loop until reached to end of file(-1)
for (unsigned b = 0; b < code[read].size(); b++) { // loop through bits (code[read] outputs huffman code)
buffer <<= 1;
buffer |= code[read][b] != '0';
bit_count++;
if (bit_count == 8) {
ofile << buffer;
buffer = 0;
bit_count = 0;
}
}
read = ifile.get();
}
if (bit_count != 0)
ofile << char(buffer << (8 - bit_count));
ifile.close();
ofile.close();
}
void decodeOutput(const string & fileName2, const string & fileName3, string code[256], const unsigned long long freq[256]) {
ifstream ifile;
ifile.open(fileName2, ios::binary);
if (!ifile)
{
die("Can't read again");
}
ofstream ofile;
ofile.open(fileName3, ios::binary);
if (!ofile) {
die("Can't open encoding output file");
}
priority_queue < node > q;
for (unsigned i = 0; i < 256; i++) {
if (freq[i] == 0) {
code[i] = "";
}
}
for (unsigned i = 0; i < 256; i++)
if (freq[i])
q.push(node(unsigned(i), freq[i]));
if (q.size() < 1) {
die("no data");
}
while (q.size() > 1) {
node *child0 = new node(q.top());
q.pop();
node *child1 = new node(q.top());
q.pop();
q.push(node(child0, child1));
} // created the tree
string answer = "";
const node * temp = &q.top(); // root
for (int c; (c = ifile.get()) != EOF;) {
for (unsigned p = 8; p--;) { //reading 8 bits at a time
if ((c >> p & 1) == '0') { // if bit is a 0
temp = temp->child0; // go left
}
else { // if bit is a 1
temp = temp->child1; // go right
}
if (temp->child0 == NULL && temp->child1 == NULL) // leaf node
{
answer += temp->value;
temp = &q.top();
}
}
}
ofile << ans;
}