【问题标题】:Huffman compression reading file does not copy all the bytes in the binary file c++霍夫曼压缩读取文件不复制二进制文件c++中的所有字节
【发布时间】:2016-05-03 06:44:43
【问题描述】:

我的程序是霍夫曼压缩,一切都很好,除了一件烦人的事情。 当我从压缩文件中读取字节时,只有大约三分之一的字节被复制并解压缩(回到普通文本)。 我真的不知道问题出在哪里。 这是从文件中读取字节并将其返回到 STL 容器的函数:

template<class Container>
Container readcompressfile(string ifileloc) {
    ifstream ifile(ifileloc);

    if (!ifile) {
        throw runtime_error("Could not open " + ifileloc + " for reading");
    }

    noskipws(ifile);

    return Container(istream_iterator<uint8_t>(ifile), istream_iterator<uint8_t>());
}

这是我在解压函数中调用它的方式(如果它重要,它会调用我包含在它下面的另一个函数)(在一个类中):

void decompressfile(string loc) {
        vector<uint8_t> vecbytes(readcompressfile<vector<uint8_t>>(ifilelocation)); // Here is where I'm using the above function

        vector<uint8_t>::iterator iter = vecbytes.begin();

        uint8_t ctr = 0xFF;
        bitset<8> b2 = 0;
        string code = "";

        for (; iter != vecbytes.end(); ++iter) {
            b2 = ctr & *iter;

            for (int i = 7; i >= 0; i--) {
                code += to_string(b2[i]);
            }
        }

        decodetext(code, loc);
    }

    //Reads bits and outputs string
    void decodetext(string codetext, string ofileloc) {
        string code = "";
        string text = "";
        char lett;

        for each (char ct in codetext) {
            code += ct;
            lett = returncharmap(code);
            if (lett != NULL) {
                text += lett;
                code = "";
            }
        }

        ofstream ofile(ofileloc);
        ofile << text;
        ofile.close();
    }

压缩函数将 1 和 0 的字符串转换为位(我将它们打包成字节),然后将其存储在文件中(工作正常),至于解压缩,您已经注意到我读取了二进制文件在 readcompressfile(string ifileloc) 函数中,然后将其放入 vector&lt;uint8_t&gt; 容器中,然后将其转回 1 和 0 的字符串,然后再转回文本,并且被复制的字节会很好地解压缩。

I displayed the size of the string before and after and here is the result

注意:readcompressfile(string ifileloc) 函数是我从 stackoverflow 上的某人那里复制的,因为它解决了我之前遇到的问题。

【问题讨论】:

  • 您可以考虑使用std::istreambuf_iterator 而不是std::istream_iterator。那么你至少不必担心“空白”。
  • 我用过但没用,报错

标签: c++ huffman-code


【解决方案1】:

我猜你是在 Windows 上运行的,它会将文本流中的 ^Z 字符(这是 ifstream 的默认模式)解释为文件结束指示符。

代替:

 ifstream ifile(ifileloc);

使用:

 ifstream ifile(ifileloc, ifstream::in | ifstream::binary);

如下面的cmets中所指出的,Windows平台也会在文本模式下将"\r\n"字符序列转换成单个字符"\n"

【讨论】:

  • 这不是 Windows 上唯一的问题,更常见的是换行符转换("\r\n""\n")。
  • 确实如此 - 应该提到这一点。发布的示例中的大小差异很大(应该作为文本复制/粘贴到问题中)让我直接进入 EOF。
  • 实际上是问题所在,谢谢你现在它工作得很好
猜你喜欢
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多