2

我想解析一个字符缓冲区并将其存储在数据结构中。缓冲区的第一个 4 个字节指定名称,第二个四个字节指定值的长度 (n),接下来的 n 个字节指定值。

例如:char *buff = "aaaa0006francebbbb0005swisscccc0013unitedkingdom"

我想从缓冲区中提取名称和值并将其存储为数据结构。例如: char *name = "aaaa" char *value = "france"

char *name = "bbbb"
char *value = "swiss"

存储后,我应该能够使用名称访问数据结构中的值。我应该使用什么数据结构?

编辑(来自评论):我尝试了以下方法:

struct sample { 
    char string[4]; 
    int length[4]; 
    char *value; }; 

struct sample s[100]; 

while ( *buf ) { 
    memcpy(s[i].string, buf, 4); 
    memcpy(s[i].length, buf+4, 4); 
    memcpy(s[i].value, buf+8, s.length); 
    buf += (8+s.length); 
}

我应该三次调用 memcpy 吗?有没有办法通过只调用一次 memcpy 来做到这一点?

4

3 回答 3

2

为了扩展您新提供的信息,这会更好:

struct sample { 
    char string[4]; 
    int length; 
    char *value; }; 

struct sample s[100]; 

while ( *buf && i < 100) { 

    memcpy(s[i].string, buf, 4); 

    s[i].length = atoi(buf+4); 

    s[i].value = malloc(s[i].length);
    if (s[i].value)
    {
         memcpy(s[i].value, buf+8, s[i].length); 
    }
    buf += (8+s[i].length); 
    i++;

}

于 2013-01-18T12:45:31.423 回答
2

根本不使用memcpy怎么样?

typedef struct sample { 
    char name[4]; 
    union 
    {
        char length_data[4];
        unsigned int length; 
    };
    char value[]; 
} sample_t; 

const char * sample_data = "aaaa\6\0\0\0francebbbb\5\0\0\0swisscccc\15\0\0\0unitedkingdom";

void main()
{
    sample_t * s[10];
    const char * current = sample_data;
    int i = 0;

    while (*current)
    {
        s[i] = (sample_t *) current;
        current += (s[i])->length + 8;
        i++;
    }

    // Here, s[0], s[1] and s[2] should be set properly

    return;
}

现在,您永远不会明确指定表示长度的 4 个字节是包含字符串表示还是实际的二进制数据;如果是四个字符需要通过atoi()或类似的,那么你需要做一些后处理,比如

    s[i]->length = atoi(s[i]->length_data)

在结构可用之前,这反过来意味着源数据必须是可写的并且可能在本地复制。但即便如此,您也应该能够一次复制整个输入缓冲区,而不是把它切碎。

另外,请注意,这依赖于使用此结构的任何内容都尊重长度字段,而不是将值字段视为以空字符结尾的字符串。

最后,使用像这样的二进制整数数据显然是依赖于架构的,并具有以下所有含义。

于 2013-01-18T13:21:01.200 回答
1

我会这样做:我将定义一个可变长度结构,如下所示:

typedef struct { 
    char string[4]; 
    int length[4]; 
    char value[0] } sample;

现在,在解析时,将字符串和长度读入临时变量。然后,为结构分配足够的内存。

uint32_t string = * ( ( uint32_t * ) buffer );
uint32_t length = * ( ( uint32_t * ) buffer + 4);
sample * = malloc(sizeof(sample) + length);
// Check here for malloc errors...
 * ( (uint32_t *) sample->string) = string;
 * ( (uint32_t *) sample->length) = length;
memcpy(sample->value, ( buffer + 8 ), length);

这种方法将缓冲区的整个上下文保持在一个连续的内存结构中。我用它所有的时间。

于 2013-01-18T13:53:54.317 回答