为了准备即将到来的面试们,把以前的RPG项目拿出来安装到手机上跑了跑,发现游戏会卡死,简直郁闷。。。
当初我写完这个项目的时候,android 5.0还没有发布,我在android 2.3到android 4.4的设备上都测试通过了(作为穷逼的我,自己的手机就是2.3。。),现在终于换手机了,刷了CM12(android 5.0.2),果然出现bug了,游戏会莫名卡死。。。
测试了一个小时,终于把错误范围锁定在一个读取文件的函数中,然后一点一点的注释函数中的某些行,最终发现是sscanf函数引发了卡死的问题,虽然修改很容易,但是在发现错误的过程中浪费了不少时间,只能是警惕自己,以后做C++的时候慎用C库函数吧。。
吐槽了这么长,最后写一下解决办法吧,虽然很简单。。
众所周知,sscanf的功能是从一个字符串(char*)中格式化读取数据,例如
1 const char* str = "10 3.14 haha"; 2 int x; 3 double y; 4 char z[1024]; 5 sscanf(str, "%d %lf %s", &x, &y, z); 6 printf("%d %.2lf %s\n", x, y, z);
这段代码会输出 "10 3.14 haha"。
相应的,还有格式化输出到字符串的函数sprintf,用法相似,就不细说了。
这是C库的函数,在C++中对应的应该怎么做呢?可以用stringstream做到,其实用法比这两个C库函数还要简单,所以更加没必要用C库函数了。用stringstream改写上面的代码就是这样:
1 #include <sstream> 2 #include <iostream> 3 #include <string> 4 5 using namespace std; 6 7 int main() { 8 const char * str = "10 3.14 haha"; 9 stringstream stream; 10 stream << str; 11 int x; 12 double y; 13 string z; 14 stream >> x >> y >> z; 15 cout << x << " " << y << " " << z << endl; 16 return 0; 17 }
多次使用一个stringstream时,调用stream.str("")清空未读取的流,调用stream.clear()来清除错误标记。
感觉NDK真的很脆弱,经常遇到用GCC和VS都毫无警告的代码,拿到android上就闪退,调试原本就正确的代码真的不是一件愉快的事情。。。