2

文字バッファーを解析し、データ構造に格納したいと考えています。バッファーの最初の 4 バイトは名前を指定し、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 を 3 回呼び出す必要がありますか? 一度だけ memcpy を呼び出す方法はありますか?

4

3 に答える 3

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()などを実行する必要があるのが 4 文字の場合は、次のような後処理を行う必要があります。

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

これは、ソース データが書き込み可能であり、おそらくローカルにコピーされている必要があることを意味します。ただし、それでも、入力バッファー全体を切り刻むのではなく、一度にコピーできるはずです。

また、これは、値フィールドをヌル終了文字列として扱うのではなく、長さフィールドを尊重するこの構造体を使用するものに依存していることに注意してください。

最後に、このような 2 進整数データの使用は明らかにアーキテクチャに依存し、それに続くすべての影響があります。

于 2013-01-18T13:21:01.200 に答える
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 に答える
1

次のように、可変長構造を定義します。

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

now 、解析中に、文字列と長さを一時変数に読み取ります。次に、構造体に十分なメモリを割り当てます。

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);

このアプローチでは、バッファのコンテキスト全体が 1 つの連続したメモリ構造に保持されます。いつも使っています。

于 2013-01-18T13:53:54.317 に答える