如何从字节数组中获取数据

时间:2012-10-08 08:55:29

标签: c parsing struct client-server bytearray

有关任务的一般信息:

我需要在 C语言上编写函数,它接受一个字节数组(它重复包)解析它,做一些事情并返回一个更改的字节数组。

我的方法:

"filename.h"
    char* ParsePackage(const char* byteArray);
typedef struct
{
    char name[4];
    float value;
} packageStructure;

我使用构造byteArray的struct packageStructure,然后我试图通过访问该结构的字段来获取数据: “filename.cpp”

include "filename.cpp"
char* ParsePackage(const char* byteArray)
{
    packageStructure* tmp = (packageStructure*) byteArray;
    // get values of structure fields and do some staff with them:
    tmp->name;
    tmp->value;
    return (char*)modifiedByteArray;
}

对结果不满意,因为来自字节数组的整个数据被写入结构的第一个字段,这是一个名称,对第二个字段有一些随机值; < / p>

所以这里的预期问题是:我做错了(如何改变我的做法)?你能提供其他解析字节数组的方法吗?

提前致谢!

4 个答案:

答案 0 :(得分:3)

我猜测"tex"应该是名称,123应该是值。但是,您可以看到它不起作用,尤其是浮点值。您不能仅通过强制转换将字符串中的数字转换为浮点值。

相反,您必须从字符串中提取前三个字符并放入name,然后您必须提取接下来的三个字符并作为字符串使用,例如strtof将字符串转换为浮点数。

再次创建字符串时,可以使用snprintf

你必须做这样的事情:

char* ParsePackage(char* byteArray)
{
    packageStructure tmp;

    /* Extract values from string, first the name */
    memcpy(tmp.name, byteArray, sizeof(tmp.name) - 1);
    tmp.name[sizeof(tmp.name) - 1] = '\0';  /* Make sure it's terminated */

    /* Then the value */
    tmp.value = strtof(&byteArray[3], NULL);

    /* Now do whatever you need to do with the structure... */

    /* Convert back to a string */
    /* For that we need a string */
    static char output[16];

    /* Then put the data from the structure into the string */
    snprintf(output, sizeof(output), "%s%3.0f", tmp.name, tmp.value);

    /* Return the string */
    return output;
}

但是,您应该找到serialization的库,而不是自己完成这项工作,该库将为您处理所有的血腥细节。

答案 1 :(得分:1)

我不确定你想要什么,但似乎你想把名字当作字符串使用,当输入是字符串时,你想把它当作浮点数。

我会这样做:

packageStructure ParsePackage(char* byteArray)
{
    char *modifiedByteArray = malloc(100);
    packageStructure tmp;
    strncpy( tmp.name, byteArray, 3 );
    tmp.name[3] = 0;
    tmp.value = atof(byteArray+4);
    return tmp;
}

答案 2 :(得分:0)

int main(void) { ParsePackage("tex123"); return 0; }

根据代码,您的文字"tex123"是只读的。

.LFE0:
        .size   ParsePackage, .-ParsePackage
        .section        .rodata
.LC0:
        .string "tex123"
        .text
        .globl  main
        .type   main, @function
main:
.LFB1:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, 
        ....
        ....

所以试图改变string literal是一个坏主意。

答案 3 :(得分:0)

在我的实验中,我发现可以将一个字节数组转换为结构。这允许以更优雅(我自己的观点)的方式解决反序列化任务。

我的第一次尝试失败了,因为我在错误的输入上测试了它们,这是一个字符串文字。 以下是工作示例:

".h"
typedef struct Test
    {
        char name[2] ;
        float number;
    } Test;

".c"
char* TestStruct(char* byteArray)
{
    Test str;

    str = *(Test*)byteArray;
    return byteArray;
}
"main.c"
int main(void)
{
    Test str;
    strcpy(str.name,"asd\0");
    str.number = 0.25;
    TestStruct((char*)&str);
    return 0;
}