Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在数据缓冲区中处理标头_C - Fatal编程技术网

C 在数据缓冲区中处理标头

C 在数据缓冲区中处理标头,c,C,我有一个包含以下内容的数据缓冲区: 00000000 20 7F 3E 15 38 34 37 2E 38 33 33 36 38 32 20 2F 00000010 20 31 33 2E 30 30 35 34 31 39 20 3E 20 20 20 20 00000020 20 3E 20 4E 4F 20 47 50 53 20 44 41 54 41 20 20 00000030 20 20 20 20 20 20 20 20 20 20 20 20

我有一个包含以下内容的数据缓冲区:

00000000    20 7F 3E 15 38 34 37 2E 38 33 33 36 38 32 20 2F
00000010    20 31 33 2E 30 30 35 34 31 39 20 3E 20 20 20 20    
00000020    20 3E 20 4E 4F 20 47 50 53 20 44 41 54 41 20 20
00000030    20 20 20 20 20 20 20 20 20 20 20 20
现在我想用“真实”数据在另一个函数中处理它

“真实”数据是前5个字节之后的所有数据。第五个字节(在本例中为0x38)是数据长度。现在如何扫描缓冲区中的头0x20 0x7F 0x3E 0x15和数据长度字节,并将实际数据内容移动到另一个缓冲区,或者更好,将当前缓冲区仅剥离到数据内容

注意:我不能动态分配内存。 缓冲区大小始终为60字节(包括标头)


谢谢

假设原始缓冲区至少包含5个字节:

#define CAPACITY UINT8_MAX
uint8_t buf[CAPACITY], newbuf[CAPACITY - 5];
...
int header_is_ok = 
    (buf[0] == 0x20 && buf[1] == 0x7F && buf[2] == 0x3E && buf[3] == 0x15);

if (header_is_ok) {
    uint8_t length = buf[4];

    if (length > 0 && length < CAPACITY - 5) {
        uint8_t *contents = buf + 5;
        memcpy(newbuf, contents, length);
    }
}
#定义容量UINT8_最大值
uint8_t buf[容量]、NEBUF[容量-5];
...
int header_为_ok=
(buf[0]==0x20&&buf[1]==0x7F&&buf[2]==0x3E&&buf[3]==0x15);
如果(标题为ok){
uint8_t长度=buf[4];
如果(长度>0&&长度<容量-5){
uint8_t*内容=buf+5;
memcpy(newbuf、内容、长度);
}
}

一旦知道内容的开头和长度,
memcpy
会将缓冲区移动到另一个位置。

我在这里对StackOverflow的第一个贡献,希望你会喜欢我的帮助

上面的答案很好,但我想输入我的方法。这将使您很容易跟踪标题中的不同部分,并将标题与数据分开

缺点是需要更少的注释,更容易调试等等

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>


//! Structure defining the different parts in the buffer
typedef union
{
    struct
    {
        uint8_t part1;
        uint8_t part2;
        uint8_t part3;
        uint8_t part4;
        uint8_t length;
    }header;
    uint8_t fullHeader[5];

    uint8_t *data;
}tDataInfo;


//! Size of header (in bytes)
static const uint8_t sizeOfHeader = 5;


//! Dummy data buffer
static uint8_t dataBuffer[] =
{
    0x20, 0x7F, 0x3E, 0x15, 0x0B, 0x34, 0x37, 0x2E, 0x38, 0x33, 0x33, 0x36, 0x38, 0x32, 0x20, 0x2F
};


int main()
{
    tDataInfo dataInfo;
    uint8_t *dataPtr;
    uint8_t cnt;


    // Copy header information
    memcpy(&dataInfo.header, dataBuffer, sizeOfHeader);


    // Print out header information
    printf("part1: %x\n", dataInfo.header.part1);
    printf("part2: %x\n", dataInfo.header.part2);
    printf("part3: %x\n", dataInfo.header.part3);
    printf("part4: %x\n", dataInfo.header.part4);
    printf("length: %d\n\n", dataInfo.header.length);


    // Allocate space for the data
    dataInfo.data = malloc(dataInfo.header.length);

    // Point to first byte of data
    dataPtr = dataBuffer + sizeOfHeader;

    // Copy the data
    memcpy(dataInfo.data, dataPtr, dataInfo.header.length);

    // Print out the data
    for ( cnt = 0; cnt < dataInfo.header.length; cnt++ )
    {
        printf("byte %d: %x\n", cnt, *(dataInfo.data+cnt));
    }

    return 0;
}
#包括
#包括
#包括
#包括
//! 定义缓冲区中不同部分的结构
typedef联合
{
结构
{
uint8第1部分;
uint8第2部分;
uint8第3部分;
uint8第4部分;
uint8_t长度;
}收割台;
uint8_t fullHeader[5];
uint8_t*数据;
}tDataInfo;
//! 标题的大小(以字节为单位)
静态常数8_t sizeOfHeader=5;
//! 虚拟数据缓冲区
静态uint8_t数据缓冲[]=
{
0x20、0x7F、0x3E、0x15、0x0B、0x34、0x37、0x2E、0x38、0x33、0x33、0x36、0x38、0x32、0x20、0x2F
};
int main()
{
tDataInfo数据信息;
uint8_t*dataPtr;
uint8_t cnt;
//复制标题信息
memcpy(&dataInfo.header、dataBuffer、sizeOfHeader);
//打印出标题信息
printf(“part1:%x\n”,dataInfo.header.part1);
printf(“part2:%x\n”,dataInfo.header.part2);
printf(“part3:%x\n”,dataInfo.header.part3);
printf(“part4:%x\n”,dataInfo.header.part4);
printf(“长度:%d\n\n”,dataInfo.header.length);
//为数据分配空间
dataInfo.data=malloc(dataInfo.header.length);
//指向数据的第一个字节
dataPtr=dataBuffer+sizeOfHeader;
//复制数据
memcpy(dataInfo.data、dataPtr、dataInfo.header.length);
//把数据打印出来
对于(cnt=0;cnt
此解决方案与前面的解决方案类似,但功能更强。这意味着机器使用little endian格式:

#include <stdio.h>
#include <stdint.h>

    typedef struct    //pseudo structure describing the header and the data
    {
        int_16 key;   //first 4 bytes as device key
        unsigned char length;    //length of data not including the 5 header bytes
        char  data[1]    //pseudo array of buffer data
    } DATA;

    #define KEY 0x153e7f20    //The first 4 bytes used as a key to check for device
    #define BUFSIZE 60        //buffer size

    // The function return TRUE if any data is transferred to the buffer
    BOOL ReadData(char *RawData, char *buf)
    {
         DATA *pdata = RawData;
         if (KEY != pdata->key)
             return FALSE;

         memcpy(buf, pdata->data, pdata->length <= BUFSIZE ? pdata->length : BUFSIZE);

         return TRUE;
    }
#包括
#包括
typedef struct//描述头和数据的伪结构
{
int_16 key;//前4个字节作为设备密钥
unsigned char length;//不包括5个头字节的数据长度
char data[1]//缓冲区数据的伪数组
}数据;
#定义键0x153e7f20//用作检查设备的键的前4个字节
#定义BUFSIZE 60//缓冲区大小
//如果有数据传输到缓冲区,则函数返回TRUE
BOOL ReadData(char*RawData,char*buf)
{
DATA*pdata=RawData;
如果(键!=pdata->KEY)
返回FALSE;
memcpy(buf,pdata->data,pdata->length-length:BUFSIZE);
返回TRUE;
}

嗯,你说“真正的”数据是前5个字节之后的所有内容”和“第5个字节是数据长度”。那么,为什么您认为需要“扫描”缓冲区中的标头?因为我想知道我收到的数据是否来自已知的源/设备,因此每次我都需要检查标头。在“剥离”缓冲区后,您还需要前五个字节吗?为什么要从数据中剥离标头?只需将指向缓冲区的指针传递给函数,并处理从第5个字节开始的数据。检查标头后,我不再需要信息,因此标头可以剥离。为了完整性,您可能需要定义
newBuf
以及
CAPACITY\u OF_BUF
.Hu,为什么
UINT8\u MAX
而不仅仅是
60
?因为
length
是一个字节,可以是
UINT8\u MAX