大家都知道map内部是按照平衡二叉树来设计的,所以无论是直接写
如
map<string, string> str_map;
str_map["alex"] = "yes?";
str_map["Alex"] = "no!";
之后,这个map里的顺序就是
Alex-no!
alex-yes?
当然,这是我之后才顿悟到的. :)
具体问题是这样,我简化一下,由于需要在buf里写入值,再存到map<string, string>里
sprintf(buf, "Instance -%d is OK", i+1);
ID_ = buf;
sprintf(buf, "Instance -%d is prepared", i+1);
if ( str_map.find( ID_ ) == str_map.end() ) //若ID_不存在,则添加进去
str_map[ID_] = boost::lexical_cast<string> (buf);
之后,这个map会被写到html文件里。
结果当Instance > 9时,问题出现了。
Instance -1 is prepared
Instance -10 is prepared
Instance -11 is prepared
Instance -12 is prepared
Instance -2 is prepared
Instance -3 is prepared
Instance -4 is prepared
Instance -5 is prepared
Instance -6 is prepared
Instance -7 is prepared
Instance -8 is prepared
Instance -9 is prepared
然后我苦思冥想,难道map插入有问题? 查了STL,它就是这样子的啊,一个个比较。
接着调试,终于发现了问题,当还是第九个的时候,序列一直是顺序的,当到第十个时,它就直接插在了1的后面,变成了
Instance -1 is prepared
Instance -10 is prepared
Instance -2 is prepared
Instance -3 is prepared
Instance -4 is prepared
...
Instance -9 is prepared
看来这下问题找到了,下面分析一下,既然是string的比较,那就是一个个字符的比较,原来当比较到‘-’字符的时候还是相等的,直到1 与 10 的1比较时还是相等,结果,Instance1的下一个字符是空格,ASC码为32,而Instance10的下一个字符时'0',48,所以,Instance10就放到了Instance1和Instance2的中间,后来插入的也是这样。
下面开始解决问题:
一开始很愚蠢,很想找到一个可以直接插到map最后的位置的,类似vector的push_back的方法,结果无果。。。后来,哈哈,想到了一个以前用过的语法
就是 %0nd(n可以是0-9的数字)
作用是,当数值位数小于n的话,前面补0
如
%05d 那么原来的数字9 就变成了00009;345就变成了00345;21232还是21232
现在回到刚才的问题,我将%d改成了%03d (为了防止Instance大于100又出现问题,就用了03d)
sprintf(buf, "Instance -%03d is OK", i+1);
ID_ = buf;
sprintf(buf, "Instance -%d is prepared", i+1);
if ( str_map.find( ID_ ) == str_map.end() ) //若ID_不存在,则添加进去
str_map[ID_] = boost::lexical_cast<string> (buf);
哈哈,结果终于正确了。
Instance -1 is prepared
Instance -2 is prepared
Instance -3 is prepared
Instance -4 is prepared
Instance -5 is prepared
Instance -6 is prepared
Instance -7 is prepared
Instance -8 is prepared
Instance -9 is prepared
Instance -10 is prepared
Instance -11 is prepared
Instance -12 is prepared
小结:
这次问题给我的启发是,如果想让map<stirng, boost::any> 里的string 键按照里面的数字顺序排列的话,就得考虑一下数字的位数一定要相等,否则,不好比较,而且这个问题还在一定范围限度之外才能体现出来,所以,以后遇到要万分小心!
当然,若了解了这些容器的本质将会更加快速定位问题。
如果有更好的方式解决,一定留言交流下噢