c语言开发随笔---memcpy使用

文章讲述了如何使用C语言的memcpy函数将16位数据结构体存入8位FRAM中,以适应不同数据类型的转换需求,同时指出可能存在的大小端存储差异和结构体复制时的注意事项。
摘要由CSDN通过智能技术生成

一、场景需求:

因为使用8位FRAM做数据缓存,但采样数据是16位,需要将u16类型数据存入u8类型的数组,考虑到数据存入后还需要读取,且采样通道数量会变化,要方便添加更改,所以采用结构体的形式直接将结构体整个数据存入u8类型数组,最后通过spi存入FRAM。

二、原理:

本质上,无论是数组还是结构体,都是一块内存,所以无论怎么存入,只要读取的顺序一致,就能确保数据准确。c语言中恰好有库函数memcpy(),此函数的作用就是将一块内存复制到另一块内存,声明如下。

void *memcpy(void *str1, const void *str2, size_t n)

str1 – 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
str2 – 指向要复制的数据源,类型强制转换为 void* 指针。
n – 要被复制的字节数。

三、示例:

#include "stdio.h"
#include "string.h"

typedef struct
{
    __int16 a;
    __int16 b;
}test;

int	main()
{
    printf("*******************************************\n");
    __int8 test3[4];
    test struTest3 = {1234,5678};
    memcpy(test3, &struTest3, sizeof(struTest3));
    printf("struTest3.a = %x\n",struTest3.a);
    printf("struTest3.b = %x\n",struTest3.b);
    printf("test3[0] = %x\n", test3[0]);
    printf("test3[1] = %x\n", test3[1]);
    printf("test3[2] = %x\n", test3[2]);
    printf("test3[3] = %x\n", test3[3]);
    
    test struTest3_1;
    memcpy(&struTest3_1, &test3, sizeof(test3));
    printf("struTest3_1.a = %x\n",struTest3_1.a);
    printf("struTest3_1.b = %x\n",struTest3_1.b);
    printf("*******************************************\n");
    __int8 test4[4] = {12,34,56,78};
    test struTest4;
    memcpy(&struTest4, test4, sizeof(test4));
    printf("test4[0]= %x\n", test4[0]);
    printf("test4[1]= %x\n", test4[1]);
    printf("test4[2]= %x\n", test4[2]);
    printf("test4[3]= %x\n", test4[3]);
    printf("struTest4.a = %x\n", struTest4.a);
    printf("struTest4.b = %x\n", struTest4.b);
    __int8 test4_1[4];
    memcpy(test4_1, &struTest4, sizeof(struTest4));
    printf("test4_1[0]= %x\n", test4_1[0]);
    printf("test4_1[1]= %x\n", test4_1[1]);
    printf("test4_1[2]= %x\n", test4_1[2]);
    printf("test4_1[3]= %x\n", test4_1[3]);
    return 0;
}


运行结果:

*******************************************
struTest3.a = 4d2
struTest3.b = 162e
test3[0] = ffffffd2
test3[1] = 4
test3[2] = 2e
test3[3] = 16
struTest3_1.a = 4d2
struTest3_1.b = 162e
*******************************************
test4[0]= c
test4[1]= 22
test4[2]= 38
test4[3]= 4e
struTest4.a = 220c
struTest4.b = 4e38
test4_1[0]= c
test4_1[1]= 22
test4_1[2]= 38
test4_1[3]= 4e

在这里插入图片描述

四、结论:

证明memcpy函数可以用来做不同数据类型的互相转换,虽然过程中一些量可能因为大小端存储方式的不同而有差异,但本次场景我只需要16位—>8位存入—>16位读取,不需要中间量,所以省去了16转8位的移位计算。
补充:memcpy对结构体数据复制到数组内还应有其他要求,比如结构体数据对齐,结构体指针成员等,这些可能在复制过程中出错,这里我就不验证了。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要解析form-data数据,需要先了解一下form-data的格式。form-data是一种常见的HTTP POST请求体格式,用于向服务器发送表单数据。其格式如下: ``` Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxyzabc ------WebKitFormBoundaryxyzabc Content-Disposition: form-data; name="field1" value1 ------WebKitFormBoundaryxyzabc Content-Disposition: form-data; name="field2"; filename="example.txt" Content-Type: text/plain file contents ------WebKitFormBoundaryxyzabc-- ``` 其中,boundary指定了分隔符。在解析form-data数据时,需要按照分隔符将数据分割成多个部分,然后对每个部分进行解析。 以下是一个简单的C语言代码示例,用于解析form-data数据: ```c #include <stdio.h> #include <string.h> int main() { char *data = "------WebKitFormBoundaryxyzabc\r\nContent-Disposition: form-data; name=\"field1\"\r\n\r\nvalue1\r\n------WebKitFormBoundaryxyzabc\r\nContent-Disposition: form-data; name=\"field2\"; filename=\"example.txt\"\r\nContent-Type: text/plain\r\n\r\nfile contents\r\n------WebKitFormBoundaryxyzabc--\r\n"; char *boundary = "------WebKitFormBoundaryxyzabc"; // find the first part boundary char *part_start = strstr(data, boundary); if (part_start == NULL) { printf("Error: cannot find the first part boundary.\n"); return 1; } // parse each part while (1) { // find the next part boundary char *part_end = strstr(part_start + strlen(boundary), boundary); if (part_end == NULL) { printf("Error: cannot find the next part boundary.\n"); return 1; } // get the part data char *part_data_start = part_start + strlen(boundary) + 2; // skip CRLF char *part_data_end = part_end - 2; // skip CRLF int part_data_len = part_data_end - part_data_start; char part_data[part_data_len + 1]; memcpy(part_data, part_data_start, part_data_len); part_data[part_data_len] = '\0'; // parse the part data char *name_start = strstr(part_start, "name=\""); if (name_start == NULL) { printf("Error: cannot find the name attribute.\n"); return 1; } name_start += 6; // skip "name=\"" char *name_end = strstr(name_start, "\""); if (name_end == NULL) { printf("Error: cannot find the end of the name attribute.\n"); return 1; } int name_len = name_end - name_start; char name[name_len + 1]; memcpy(name, name_start, name_len); name[name_len] = '\0'; char *filename_start = strstr(part_start, "filename=\""); if (filename_start != NULL) { // this is a file part filename_start += 10; // skip "filename=\"" char *filename_end = strstr(filename_start, "\""); if (filename_end == NULL) { printf("Error: cannot find the end of the filename attribute.\n"); return 1; } int filename_len = filename_end - filename_start; char filename[filename_len + 1]; memcpy(filename, filename_start, filename_len); filename[filename_len] = '\0'; printf("Part name: %s, filename: %s, data: %s\n", name, filename, part_data); } else { // this is a regular part printf("Part name: %s, data: %s\n", name, part_data); } part_start = part_end; if (part_start[2] == '-') { break; // end of data } } return 0; } ``` 该代码将form-data数据解析为多个部分,并对每个部分进行解析。如果是文件部分,会输出文件名和文件内容;否则,只输出表单字段名和值。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值