我在gcc下编译了以下代码:
int parseMsg(const char *msg_to_parse, unsigned long *exp_input, unsigned long *sysTicks )
{
int l_msg_size = strlen(msg_to_parse);
if(l_msg_size <10)
return -1;
char l_exp_input_arr[10];
char l_sys_ticks_arr[10];
memcpy(l_sys_ticks_arr,msg_to_parse+12,10);
memcpy(l_exp_input_arr,msg_to_parse,10);
//l_msg_size = strlen(msg_to_parse);
*sysTicks = strtoul(l_sys_ticks_arr,NULL,10);
*exp_input = strtoul(l_exp_input_arr,NULL,10);
return 0;
}
我试着用以下方式测试它:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int parseMsg(const char *msg_to_parse, unsigned long *exp_input, unsigned long *sysTicks );
int main(void) {
char msg[] = "1234567890 59876543213";
unsigned long along1, along2;
along1 =0;
along2=0;
parseMsg(msg,&along1, &along2 );
printf("result of parsing: \n \t Along 1 is %lu \n \t Along 2 is %lu \n",along1, along2);
return 0;
}
但是,我得到了以下结果:
分析结果:
沿1是1234567890
沿2是4294967295
为什么第二个未签名的long是错误的?
谢谢
最佳答案
您提供的第二个整数太大,无法在体系结构的内存中表示。因此,根据它的API,strtoul只是返回ULONG_MAX(=4294967295在您的体系结构中),同时将errno设置为ERANGE
strtoul API在这里:http://www.cplusplus.com/reference/clibrary/cstdlib/strtoul/
但是,如果给出一个较小的整数,它也可能失败,因为strtoul只在遇到非数字字符时停止解析。由于您没有确保这一点,因此您无法确保strtoul不会尝试解析字符串后面内存中的任何内容。(所以假设是随机的,256次中有10次有转换错误)
用\0终止字符串,这样就可以了:
char l_exp_input_arr[11]; // +1 for \0
char l_sys_ticks_arr[11];
memcpy(l_sys_ticks_arr, msg_to_parse+12, 10);
l_sys_ticks_arr[10] = '\0';
memcpy(l_exp_input_arr, msg_to_parse, 10);
l_exp_input_arr[10] = '\0';