内容纲要
atoi (表示ascii to integer)是把字符串转换成整型数的一个函数,应用在计算机程序和办公软件中。
int atoi(const char *nptr) 函数会扫描参数nptr字符串,会跳过前面的空白字符(例如空格,tab缩进)等。
如果nptr不能转换成int 或者nptr为空字符串,那么将返回0 。
小心字节对齐方面的问题: 以及返回类型不能是引用类型,容易变成野指针。
内存对齐,在结构体中,内存往往都是4或者8 的整数倍,如果想要结构体定义成想要的内存的形式,可以进行如下操作 使用 #pragma pack(1)
#pragma pack(1)
struct dev_Info
{
/* data */
uint8_t ver;
uint8_t plevel;
uint16_t cel; // 2字节
uint16_t rssi; // 2 字节
uint16_t rsrp; // 2 字节
uint16_t rsrq; // 2 字节
uint16_t snr; // 2字节
};
struct sensor_Info
{
/* data */
uint8_t ct;
uint16_t volt;
uint16_t tp1;
uint16_t tp2;
uint16_t tp3;
uint8_t upd[3]; // 三个字节就用数组来实现
uint16_t stp;
uint8_t srh;
uint8_t way;
};
typedef struct
{
/* data */
struct
{
char imei[16]; // 这后面 有一个\0 要算进去
char imsi[16];
char iccid[21];
} sim_Info;
struct dev_Info dev;
struct sensor_Info sensor;
} cm_info_t;
#pragma pack()
itoa( ) 与 atoi( ) 函数 以及 sscanf( )
-
关于C中数组初始化,其数组长度不能是变量,不然编译器会报错,编译器在编译过程中不能确定开辟内存大小(哪怕你的变量是知道的,但是它是sizeof( ) 出来的 )。
解决办法:
char * const test = (char *)malloc(size);
使用malloc 开辟空间,记得要释放哈,const 也能去掉, 不过加一个const 保证指针test 不会修改它的指向
int size = sizeof(uploadDATA);
// char test[size] = {0}; // C中不能动态初始化 数组,也就是数组长度不能是变量
char * const test = (char *)malloc(size);
-
数组的拷贝
-
值得注意的点:
- 使用
cm_sim_get_imsi(&imsi);
拷贝出来的字符串长度 和结构体uint8_t 的长度不同,uint8_t 长度应该为字符串拷贝的一半,因为它一次把 2 个字符 转成16进制 进行存储。 - 这里找到的问题,
- 使用
比对
- imsi[8] 的时候的数组情况
-
imsi[16] 时候
大的问题点
数组越界:
-
结构体中,创建了3个 变量,在这边给结构体初始化的时候,内存分配的空间没给够,导致数组越界!!,离谱,造成的结果是:因为
iccid[]
数组长度没给够,使得imsi
获取的值被 iccid 乱传值,遇到此BUG。
结构体数据处理,
- 之前我考虑的是,由于 整个大结构体中 只有 imei 、 imsi 、iccid 三个变量是
字符串
,别的都是 基本数据类型,所以我打算把这3个变量做成 uint8_t 。所以问题就出现了。
- 做成 基本数据类型的时候, imei 占用15 个字符长度, 而且 基本数据类型的数组后面都有
\0
, 这个问题处理起来比较棘手。 - 那便是 string 类型转化为 int 类型比较麻烦。特别麻烦。用 sscanf( ) 函数也不方便。
解决办法:把待传的参数做成一整个长字符串,就没这么多问题了。
TIP: 大部分时候memcpy() 比 遍历赋值好用得多
关于MN316 开发板的电压获取函数的问题,导致的结果是获取iccid 报错
- 关注点:
- 通过指针来 进行结构体的数据拷贝,更简单。
- 使用malloc 来进行数组的动态创建。(一般数组的长度不能是变量,但是malloc 可以实现数组这个功能)
/* 创建指针,指针指向后续需要把 整形 转化为字符串类型的第一个地址。
通过长度来进行数据拷贝做成字符数组 */
int uint_SIZE = sizeof(uploadDATA.dev) + sizeof(uploadDATA.sensor);
// uint8_t toArray[29] = {0}; // 这里使用 malloc 开辟内存, 动态初始化数组,提高灵活性
uint8_t *const toArray = (uint8_t *)malloc(uint_SIZE); // 本质就是数组(指针常量,指针不可变,即为引用&)
uint8_t *pStruct = &uploadDATA.dev.ver; // 创建结构体指针,
char *const temp = (uint8_t *)malloc(uint_SIZE);
// char temp[29] = {0}; //由于数组开辟内存的时候不能使用变量开辟
memcpy(toArray, pStruct, uint_SIZE); // !!通过指针进行内存的拷贝,数据大小为uint8_t 需要转化为string 的长度
ArrayToStr(toArray, sizeof(toArray), temp); //toArray 转化为 temp字符串
cm_demo_printf("temp == %s \n", temp);
cm_demo_printf("sizeof(temp) == %d \n", sizeof(temp));
(还是尽量少用char *const temp = (uint8_t *)malloc(uint_SIZE);
避免忘记释放内存而翻车)
- 在这个项目中,我没有使用指针 构建动态数组,估计是我
malloc
之后没有用memset
初始化内存,导致有问题,所以我还是老老实实使用的数组来存放数据