当前位置: 首页 > 代码生活, 我的研究 > 正文

记最近遇到的几个小问题(字符串转整型溢出,汉字乱码,双网卡双默认IP)

这个月很少写文章,因为做着项目。说来惭愧,人当项目经理,我当项目经理,我却既像爹又像娘,似乎凡事亲力,同志们太依赖项目经理了。什么编译环境、SVN提交代码,周报提交,无一不是问过于我。我想不理这事,无奈有的领导太忙,有的开发人员太懒,而我又是“老好人”,只想项目快点结束,于是就出现这种情况了。不过,最主要还是有人推我下坑,说我以前做项目的管理能力行,所以叫我做项目经理了。我都没当过项目经理,哪来的管理能力。更何况,这次不但给的人少(我这个兼职的PM,人员都是安排好了再叫我当的),还有一个未参加过项目,连SVN都不熟的成员。
至少遇到的问题,大部分是项目本身代码的问题,没什么值得学习的。倒是有两个小问题,还可以记录一下。
第一个问题是字符串转换成整型有可能溢出的问题。项目中使用的时间戳是使用2个32位无符号数来存储毫秒数的,这个数地很大的。对于32位无符号数来说,存储时间的确是足够的。——至于2038年问题,现在还没到,先不管。本身的设计无问题,但却在函数的使用上有问题,整体表现出来就是有问题的。——正如项目的制度流程,本身出发点是没问题的,但万一执行的人出了差错,在公司领导来看,项目做得就不好。比如,我这个PM就延期了2次,被大领导和其它管理项目的人抨击了。
对于一般情况,用atoi无问题,但对于上面所说的一些较大的数,就有风险了。因为atoi只能转换成int,最大只能是2147483647,但超过这个范围,比如32位无符号数(最大值为4294967295),就溢出了。对比时间戳来说,是很容易溢出的。我们的设备都是32位系统,int和long都是4个字节(32位)。即使用atol也解决不了。解决方法是使用strtoul。示例代码如下:

int aoti()
{
    char* p = "2147483649";
    unsigned int a = 0;
    a = atoi(p); // 32位机器得到2147483647 是int的最大值
    printf("p: %s a: %u\n", p, a);
    a = strtoul(p, NULL, 10); // 用strtoul转换正常
    printf("p: %s a: %u\n", p, a);
    return 0;
}

另外一个问题是汉字编码,我们设备用linux系统,但客户需要查看数据却使用windows系统。在检测自测情况下,发现有个另txt文件记录的数据是乱码,但其它大部分都正常。比如“蓝鲁11111”,在记事本里保存后,得到的就是乱码,但“白鲁11111”却能正常显示。这种问题可以被发现,真的很幸运,车牌那么多,偏偏被误识为“蓝鲁”——感谢我那不熟悉的业务操作水准。由此又再次体现到乱码造成的困扰。
经过一番对比,发现是GB编码和UTF8的问题。如下的代码:

int main(void)
{
    char* str = "蓝鲁ala";

    my_write_file("test.txt", str);
    
    return 0;
}

假如源码文件编码格式是GB2312的话,保存的test.txt文件用记事本打开就有乱码,但如果源码文件编码格式用UTF8,则就问题。对比后,发现fwrite的函数调用,会根据当前的文件格式来决定数据写入的格式。我认为特定的某些汉字,在编码上可能存在问题。再测试发现,如果统一用UTF8,则不会有此问题。示例代码如下:

int gb2312toutf8(char *sourcebuf,size_t sourcelen,char *destbuf,size_t *destlen) 
{   
    int ret;
    iconv_t cd;
    char **source;
    char **dest;    
    
    if( (cd = iconv_open("utf-8","gb2312")) ==0 )     
        return -1;   
 
    source = &sourcebuf;   
    dest = &destbuf;
    ret = iconv(cd,source,&sourcelen,dest,destlen);    
    iconv_close(cd);   
    
    return ret;   
}

int main(void)
{
    const char* file = "test.txt";
    char* str = "蓝鲁ala";
    char utf8[32] = {0};
    int utf8_len = 32;

    my_write_file("org.txt", str);
    
    gb2312toutf8(str, strlen(str), utf8, &utf8_len);
    my_write_file(file, utf8);

    return 0;
}

再次运行得到的test.txt,就显示正常了。
经过自己尝试及网络搜索,使用windows系统的记事本保存如liantong(如连同、连通)、lanlu(拦路、蓝路、蓝鲁),都会有问题。
还有一个问题,我们的设备是双网卡,当初的产品定位时,人为地区分了内、外网,并且内网使用默认值,不对外提供。但现在的实际情况和当初的定位有出入,需要对外提供内网IP的设置操作。但最近测试发现网络的bug连连。经过分析找到原因,一来我对双网卡研究不深,二来公司架构的代码接口本身有问题。每次设置IP时,都会设置默认网关——不管有多少网卡。所以系统就有了2个默认网关了。

本文固定链接: http://www.latelee.org/code-life/int-gdk-double-netcard.html

目前暂无评论

发表评论

*

快捷键:Ctrl+Enter