0

タスクに関する一般情報:

バイト配列(パッケージを表す)を取り、それを解析し、いくつかの処理を実行して、変更されたバイト配列を返すC言語で関数を作成する必要があります。

私のアプローチ:

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

byteArrayがキャストされるstructpackageStructureを使用し、そのstructのフィールドにアクセスしてデータを取得しようとしています: "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;
}

バイト配列からのデータ全体が構造体の最初のフィールド(名前)に書き込まれ、2番目のフィールドにランダムな値が書き込まれるため、結果に満足できません。

ここで予想される質問は次のとおりです。私が間違っていること(アプローチを変更して機能させる方法)?バイト配列を解析する他の方法を提供できますか?

前もって感謝します!

4

4 に答える 4

3

"tex"それが名前であり、価値であると私は推測して123います。ただし、ご覧のとおり、特に浮動小数点値の場合は、そのようには機能しません。文字列内の数値をキャストするだけでは浮動小数点値に変換することはできません。

代わりに、文字列から最初の3文字を抽出してに入れるname必要があります。次に、次の3文字を抽出し、文字列として、たとえば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;
}

ただし、この作業を自分で行う代わりに、シリアル化用のライブラリを見つける必要があります。このライブラリは、すべての厄介な詳細を処理します。

于 2012-10-08T09:11:10.050 に答える
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;
}
于 2012-10-08T09:21:41.677 に答える
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のは悪い考えです。

于 2012-10-08T09:17:04.333 に答える
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;
}
于 2012-10-08T10:22:24.230 に答える