BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #45547同步于 2010/11/2
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

C++新手,编了个压缩BMP图片的程序,有错误求改正

laksjd88
2010/11/2镜像同步6 回复
刚学C++不久,就看了C++primer,李学明老师布置了个压缩BMP图片的作业,自己写的代码,运行提示:map/set iterator not dereferencable。调了好久找到在哪出错了但是不知道为什么错了,请求牛人指导,谢谢。程序我上传了。 附件(2.1KB) practice.cpp
订阅后,新回复会通过你的通知中心匿名送达。
6 条回复
kmplayer机器人#1 · 2010/11/2
没太明白你的意思,既然是压缩,怎么没有输出啊? 改了几行,没有运行错误了. #include <vector> #include <fstream> #include <iostream> #include <string> #include <cstdlib> #include <sstream> #include <map> using namespace std; int main(int argc,char **argv) { //以二进制打开BMP图片,并将流置位于文件末尾 /* if (argc < 2) { cerr << "no input" << endl; return EXIT_FAILURE; } */ ifstream infile; infile.open("capture.bmp", ifstream::binary|fstream::ate); if (!infile) { cerr<<"can no open"<<endl; return EXIT_FAILURE; } //用multimap保存图片数据区,每个key值对应4字节 //multimap<size_t,int> xiangliang; multimap<size_t, char> xiangliang; //这里不是char? char yuansu; ifstream::pos_type end_mark = infile.tellg(); //返回末尾下一个位置 infile.seekg(1078, fstream::beg);//1078是BMP图片文件头相对数据区的偏移量 size_t cishu=0; while (infile && (infile.tellg() != end_mark)) { //一个key四个字节 for (int j = 0; j != 4; j++) { infile.get(yuansu); xiangliang.insert(make_pair(cishu,yuansu)); } ++cishu; } //infile.clear(); infile.close(); //是close? //取前100个key值为初始码书,从第101个key值开始与原始码书逐元素做比较,求绝对值差的和 typedef multimap<size_t, char>::iterator xiangliang_it; for(int i = 101; i != cishu; ++i) { xiangliang_it beg=xiangliang.lower_bound(i); xiangliang_it end=xiangliang.upper_bound(i); while (beg != end) { for (int j = 0; j != 100; ++j) { //遍历100个原始码书 xiangliang_it com_beg = xiangliang.lower_bound(j); xiangliang_it com_end = xiangliang.upper_bound(j); int sum=0; while (com_beg != com_end) { sum += abs(beg->second - com_beg->second);//与key值i的码字逐元素做比较,求绝对值差的和 ++com_beg; ++beg; } //恢复beg与com_beg初值,为下面使用 for (int time = 0; time != 4; ++time) { --beg; --com_beg; } int min_value; min_value=sum; //运行到此处无错 if (sum < min_value) { //若当前值小于前一个和,则将当前key值原始码书赋予key值为i的码字 min_value=sum; //system("pause"); while(com_beg!=com_end) { beg->second = com_beg->second; ++com_beg; ++beg; } } else { for(int T = 0; T != 4; ++T) { ++beg; } } } //for(int T = 0; T != 3; ++T) //这里不是4? for(int T = 0; T != 4; ++T) { //恢复beg,为下面使用 --beg; } } } return 0; }
laksjd88机器人#2 · 2010/11/2
【 在 kmplayer 的大作中提到: 】 : 没太明白你的意思,既然是压缩,怎么没有输出啊? : 改了几行,没有运行错误了. : #include <vector> : ................... 哦对,我对multimap做的更改,并没有体现在图片上,我编译的时候没有错误,可以通过,但是用windows的运行调试程序的时候就出错误了。 谢谢你,你能不能提示我一下或者大体给我个框架,怎么把修改后的multimap再复制回图片的数据区? 非常感谢。
kmplayer机器人#3 · 2010/11/2
又帮你找到了一些逻辑上的错误, 你先看看我说的对不对. 至于修改, 新建了文件,把头和修改后的value一次写进去即可吧. #include <vector> #include <fstream> #include <iostream> #include <string> #include <cstdlib> #include <sstream> #include <map> using namespace std; int main(int argc,char **argv) { //以二进制打开BMP图片,并将流置位于文件末尾 /* if (argc < 2) { cerr << "no input" << endl; return EXIT_FAILURE; } */ ifstream infile; infile.open("capture.bmp", ifstream::binary|fstream::ate); if (!infile) { cerr<<"can no open"<<endl; return EXIT_FAILURE; } //用multimap保存图片数据区,每个key值对应4字节 //multimap<size_t,int> xiangliang; multimap<size_t, char> xiangliang; //这里不是char? char yuansu; ifstream::pos_type end_mark = infile.tellg(); //返回末尾下一个位置 infile.seekg(1078, fstream::beg);//1078是BMP图片文件头相对数据区的偏移量 size_t cishu=0; while (infile && (infile.tellg() != end_mark)) { //一个key四个字节 for (int j = 0; j != 4; j++) { infile.get(yuansu); xiangliang.insert(make_pair(cishu,yuansu)); } ++cishu; } cout << cishu << endl; //infile.clear(); infile.close(); //是close? //取前100个key值为初始码书,从第101个key值开始与原始码书逐元素做比较,求绝对值差的和 typedef multimap<size_t, char>::iterator xiangliang_it; for(int i = 101; i != cishu; ++i) { cout << i << endl; //加个标志 xiangliang_it beg=xiangliang.lower_bound(i); xiangliang_it end=xiangliang.upper_bound(i); //while (beg != end) //这个是死循环啊!!!!!!!!!!!! 貌似一次处理一个key的4个value,while多余吧? //{ int min_value = -1; //放到这里了 for (int j = 0; j != 100; ++j) { //遍历100个原始码书 xiangliang_it com_beg = xiangliang.lower_bound(j); xiangliang_it com_end = xiangliang.upper_bound(j); int sum=0; while (com_beg != com_end) { sum += abs(beg->second - com_beg->second);//与key值i的码字逐元素做比较,求绝对值差的和 ++com_beg; ++beg; } //恢复beg与com_beg初值,为下面使用 for (int time = 0; time != 4; ++time) { --beg; --com_beg; } //这里逻辑有问题吧??? //int min_value = sum; //运行到此处无错 if (sum < min_value) //永远一样啊. { //若当前值小于前一个和,则将当前key值原始码书赋予key值为i的码字 min_value=sum; //system("pause"); while (com_beg != com_end) { beg->second = com_beg->second; ++com_beg; ++beg; } } else { for(int T = 0; T != 4; ++T) { ++beg; } } } //for(int T = 0; T != 3; ++T) //这里不是4? for(int T = 0; T != 4; ++T) { //恢复beg,为下面使用 --beg; } // } } return 0; }
laksjd88机器人#4 · 2010/11/2
【 在 kmplayer 的大作中提到: 】 : 又帮你找到了一些逻辑上的错误, 你先看看我说的对不对. : 至于修改, 新建了文件,把头和修改后的value一次写进去即可吧. : #include <vector> : ................... 关于死循环: m.lower_bound(k) 返回一个迭代器,指向键不小于k的第一个元素 m.upper_bound(k) 返回一个迭代器,指向键大于k的第一个元素 我在C++ primer上看到如下代码: typedef multimap<string string>::iterator authors_it; authors_it beg=authors.lower_bound(search_item), end=authors.upper_bound(search_item); while(beg!=end){ cout<<beg->second<<endl; ++beg; } 所以我觉得不会有死循环。 关于逻辑有问题: 那个if语句永远为真吗?是不是sum在跳出while后就又变为0了? 谢谢指导啊。
kmplayer机器人#5 · 2010/11/2
你仔细看看你的beg 先加4,减4,又加4,又减4, 根本就没变. 【 在 laksjd88 的大作中提到: 】 : : 又帮你找到了一些逻辑上的错误, 你先看看我说的对不对. : : 至于修改, 新建了文件,把头和修改后的value一次写进去即可吧. : : #include <vector> : ................... 帮你弄了个输出,ms没有体现出压缩啊,你自己参考着改改吧. bless,解决问题的过程就是学习的最好途径. 加油! #include <vector> #include <fstream> #include <iostream> #include <string> #include <cstdlib> #include <sstream> #include <map> using namespace std; int main(int argc,char **argv) { //以二进制打开BMP图片,并将流置位于文件末尾 /* if (argc < 2) { cerr << "no input" << endl; return EXIT_FAILURE; } */ ifstream infile; infile.open("capture.bmp"); if (!infile) { cerr<<"can no open"<<endl; return EXIT_FAILURE; } ofstream outfile("cap2.bmp"); //用multimap保存图片数据区,每个key值对应4字节 //multimap<size_t,int> xiangliang; multimap<size_t, char> xiangliang; //这里不是char? char yuansu; ifstream::pos_type end_mark = infile.tellg(); //返回末尾下一个位置 for (int i = 0; i != 1078; i++) { infile.get(yuansu); outfile.put(yuansu); } infile.seekg(1078, fstream::beg);//1078是BMP图片文件头相对数据区的偏移量 size_t cishu=0; for (int i = 0; i != 1078; i++) { infile.get(yuansu); outfile.put(yuansu); } while (infile && (infile.tellg() != end_mark)) { //一个key四个字节 for (int j = 0; j != 4; j++) { infile.get(yuansu); xiangliang.insert(make_pair(cishu,yuansu)); } ++cishu; } cout << cishu << endl; //infile.clear(); infile.close(); //是close? //取前100个key值为初始码书,从第101个key值开始与原始码书逐元素做比较,求绝对值差的和 typedef multimap<size_t, char>::iterator xiangliang_it; for (int i = 0; i != 100; i++) { xiangliang_it beg=xiangliang.lower_bound(i); xiangliang_it end=xiangliang.upper_bound(i); while (beg != end) { outfile.put(beg->second); ++beg; } } for(int i = 101; i != cishu; ++i) { cout << i << endl; //加个标志 xiangliang_it beg=xiangliang.lower_bound(i); xiangliang_it tmp = beg; xiangliang_it end=xiangliang.upper_bound(i); //while (beg != end) //这个是死循环啊!!!!!!!!!!!! 貌似一次处理一个key的4个value,while多余吧? //{ int min_value = -1; //放到这里了 for (int j = 0; j != 100; ++j) { //遍历100个原始码书 xiangliang_it com_beg = xiangliang.lower_bound(j); xiangliang_it com_end = xiangliang.upper_bound(j); int sum=0; while (com_beg != com_end) { sum += abs(beg->second - com_beg->second);//与key值i的码字逐元素做比较,求绝对值差的和 ++com_beg; ++beg; } //恢复beg与com_beg初值,为下面使用 for (int time = 0; time != 4; ++time) { --beg; --com_beg; } //这里逻辑有问题吧??? //int min_value = sum; //运行到此处无错 if (sum < min_value) //永远一样啊. { //若当前值小于前一个和,则将当前key值原始码书赋予key值为i的码字 min_value=sum; //system("pause"); while (com_beg != com_end) { beg->second = com_beg->second; ++com_beg; ++beg; } } /* else { for(int T = 0; T != 4; ++T) { ++beg; } } */ } while (tmp != end) { outfile.put(tmp->second); ++tmp; } /* //for(int T = 0; T != 3; ++T) //这里不是4? for(int T = 0; T != 4; ++T) { //恢复beg,为下面使用 --beg; } */ // } } return 0; }
laksjd88机器人#6 · 2010/11/2
【 在 kmplayer 的大作中提到: 】 : 你仔细看看你的beg 先加4,减4,又加4,又减4, 根本就没变. : 【 在 laksjd88 的大作中提到: 】 : : : 又帮你找到了一些逻辑上的错误, 你先看看我说的对不对. : ................... OK,谢谢,我根据你说的我再自己研究研究。