c语言文件读写 huffman编码
来源:互联网 发布:纯种汉族人的特征 知乎 编辑:程序博客网 时间:2024/06/08 11:59
1.记一个大坑,在做huffman压缩时调了一个上午,如下所示,当使用w模式写入’\n’时,会被自动转化为’\r’和’\n’,而用wb则不会,a和ab同理。
FILE *fp; fopen_s(&fp, "file.dat", "w");//与wb的区别,a和ab同理 unsigned char ch = 0x0a; fputc(ch, fp); fclose(fp); fopen_s(&fp, "file.dat", "rb"); unsigned char ch1, ch2, ch3; ch1 = fgetc(fp); ch2 = fgetc(fp); ch3 = fgetc(fp); fclose(fp);
2.如何将长度不一的二进制串按一个字节一个字节的方式写入文件,注释中的想法每轮for循环,要么执行从code中取最左边一位的操作(同时i++),要么将一个完整的字节写入文件(i不增加),这样,如果同好code的最右边一位是待写入字节的第八位,则for循环中断(因为i等于code.size),则不会执行里面的if语句,导致无法正确写入。
正确的做法是在每次从code中取最左边一位之后,立即检测是否已经可以将一个完整的字节写入文件中。
while (!feof(fp1)) { code = charEntities[rawChar].code;//长度不确定的0、1串 for (int i = 0; i < code.size();) { //printf("i=%d,code.size=%d\n", i, code.size()); //cout << "i=" << i << " code.size=" << code.size() << "\n"; /*if (size == 8)//如果刚好i为code.size,则这个语句无法执行 { fputc(bcode, fp2); bcode = 0; size = 0; } else { bcode <<= 1; bcode |= code[i] - '0'; ++size; ++i; }*/ bcode <<= 1; bcode |= code[i] - '0'; cnt++; ++size; ++i; if (size == 8) { fputc(bcode, fp2);//如果用a而不是ab模式,00001010写入之后会变成0x0d0a fflush(fp2); bcode = 0; size = 0; } } rawChar = fgetc(fp1); }
3.上面过程的逆过程,将文件的内容一个字节一个字节的读出来,用一个i指示当前处理到的位置,默认i不断增加,如果文件还能继续读取,则当i走到最后时(这里是7),重新从文件中读出一个新的字节,并将i重置为0(由于for循环会自动加一,这里设为-1),这样便能够把文件中的内容全部分块取出,并按需要对每个位进行处理。
for (int i = 0; i < 8; i++) { flag = character >> 7; character <<= 1; cnt++; if (flag) { node = node->right; } else { node = node->left; } if (node->left == NULL) { fputc(node->character, fp2); totalCharacterCnt--; if (totalCharacterCnt == 0) { break; } node = root; } //当处理完最后一个字符时,从文件中重新读入1个字节 if (i == 7) { character = fgetc(fp1); if (feof(fp1)) { break; } i = -1; } }
4.下方,node->word是string类型,直接使用fwrite会出现乱码,得转成node->word.c_str(),这是将字符串写入文件的方法,对int等普通变量,如int a,只需要在写成fwrite(&a,sizeof(a),1,fp)
size = node->word.size(); //printf(">--%s--<已写入\n", node->word.c_str()); fwrite(node->word.c_str(), size, 1, fp2);
5.在将一个单词写入文件中后,要记得把word串清空,否则由于word不断增大,在调用dictionary[word].freq = freq后,会使内存急剧增大,从而导致程序崩溃。
//依次读出各个单词的内容及其频率 while (wordCnt > 0) { ch = fgetc(fp1); while (ch != specialChar) { word += ch; ch = fgetc(fp1); } fread(&freq, sizeof(int), 1, fp1); dictionary[word].freq = freq; word = "";//--?????-- wordCnt--; }
6.打开文件后一定要记得关闭,我在一个函数fopen_s打开文件后,忘记关掉,在另一个文件打调用fopen_s就无法打开文件,导致后面调用fseek和ftell 出错
- c语言文件读写 huffman编码
- Huffman哈夫曼编码译码器(文件输入输出流)C语言(C++)
- 基于Huffman编码的C语言解压缩文件程序
- Huffman树与Huffman编码(C语言实现)
- Huffman编码的c语言实现
- C语言-数据结构-哈夫曼编码-Huffman-源代码
- Huffman编码的C语言实现
- Huffman编码C实现
- HuffMan编码--文件压缩
- c语言读写文件
- C语言读写文件
- C语言读写文件
- C语言文件读写
- C语言读写文件
- C语言文件读写
- C语言文件读写
- C语言读写文件
- C语言文件读写
- QT5:C++与 QML混合编程
- mysql插入当前时间
- Unity开发HTC vive 三、远处拖动3D物体
- 1.9-1.12 Putty和Xshell远程密钥
- 支付宝掉实名余额关闭了怎么办
- c语言文件读写 huffman编码
- Linux 5种IO模型
- Unity开发HTC vive 四、传送
- 编程之路(始)
- 查找存储过程,判断mysql是否存在此列
- 高级语言程序设计实验6-9二维数组
- Torry的困惑(基本型)
- Unity开发HTC vive 五、拾取和触碰
- Windows安装pip方法