簡體   English   中英

如何在嵌套的C結構中使用靈活的數組成員?

[英]How to use flexible array members in nested C structs?

相關: 嵌套結構中的靈活數組成員

我正在嘗試將一些數據解析為一個結構。 數據包含如下組織的信息:

struct unit {

    struct unit_A {
        // 28 bytes each

        // dependency r6scA 1
        char dr6scA1_tagclass[4];
        uint32_t dr6scA1_tagnamepointer;
        uint32_t dr6scA1_tagnamestringlength;
        uint32_t dr6scA1_tagid;

        // 12 bytes of 0x00

    }A;

    // A strings

    struct unit_B {
        // 48 bytes each

        // dependency r6scB 1
        char dr6scB1_tagclass[4];
        uint32_t dr6scB1_tagnamepointer;
        uint32_t dr6scB1_tagnamestringlength;
        uint32_t dr6scB1_tagid;

        // 32 bytes of 0x00

    }B;

    // B strings

    // unit strings

}unit_container;

您可以忽略怪異的命名法。

我的行注釋// A strings// B strings// unit strings的每個包含空終止C字符串,其中與然而許多一致的號碼unit_Aunit_B ,和unit結構條目中存在的數據。 因此,如果在unit_container有5個A條目,則在它表示// A strings的位置中將有5個C // A strings

由於我不能在這些位置使用靈活的數組成員,因此我應該如何解釋在數據的這些位置上本質上未知數量的可變長度C字符串

例如,這些位置的數據可能是:

“第一個條目在這里。\\ 0第二個條目\\ 0另一個!\\ 0第四。\\ 0按任何合理的標准,此第五個條目是最好的條目。\\ 0”

...我希望我將其解釋為:

char unit_A_strings[]

...但這是不可能的。 我有什么選擇?

謝謝您的考慮。

編輯:

我認為到目前為止,最有吸引力的選擇是:

char** unit_A_strings; 指向一個char字符串數組。

如果我這樣做: char unit_A_strings[1]; 要定義一個固定大小為1個char的char數組,那么我必須放棄sizeof(unit)或類似的方法,否則就麻煩了內存分配大小,即使它對當前數據的類型最准確。 如果我執行char * unit_A_strings[1];則會發生相同的情況char * unit_A_strings[1];

另一個問題:使用char *unit_A_strings;什么區別char *unit_A_strings; char** unit_A_strings;

結論:

主要問題是結構旨在用於固定大小的信息,而我需要的是可變大小的信息存儲區域。 因此,我無法合法地將數據存儲到結構中-至少不能將其作為結構存儲。 這意味着任何其他解釋都可以,並且在我看來char**是針對這種結構情況的最佳可用選擇。

我認為它可以使用char **代替(或者您可以編寫一些結構對其進行包裝)。 例如,您可以編寫幫助功能以對流進行解碼。

char** decodeMyStream(uint_8* stream, unsigned int* numberOfCString)
{
    *numberOfCString = decodeNumberOfCString(stream);
    char** cstrings = malloc((*numberOfCString) * sizeof(char*));
    unsigned int start = 0;
    for (unsigned int i = 0; i < *numberOfCString; ++i)
    {
        usigned int len = calculateIthStringLength(stream, start)
        cstrings[i] = malloc((len) * sizeof(char));
        memcpy(cstrings[i], stream + start, len); 
        start += len
    }
    return cstrings;
}

它只是沒有思考的示例代碼,您可以想出更多更好的算法。

我認為最接近的是通過提供字符串數組:

char *AStrings[] = { "The first entry is here.",
                     "Second entry",
                     "Another!",
                     "Fourth.",
                     "This 5th entry is the bestest entry evah by any reasonable standards.",
                     NULL
                   };

注意兩件事:

  1. AStrings是一個指向字符串的指針的數組-它將是6個(請參見下面的2.)連續指針,它們指向實際字符串,而不是您在示例中使用的“ compound”字符串。
  2. 我用NULL指針結束了AStrings ,以解決“何時完成?” 題。

因此,您可以“掉到A的末端”並開始將位置視為指針-但要小心! 編譯器可能在一個變量和下一個變量之間進行各種填充,從而掩蓋了它們在內存中相對位置的所有假設,包括對其重新排序!

編輯哦! 我只是有一個想法。 從本質上講,另一種可能有用的數據表示形式是您所做的。 我對它進行了“點綴”:

char AString[] = "The first entry is here.\0"
                 "Second entry\0"
                 "Another!\0"
                 "Fourth.\0"
                 "This 5th entry is the bestest entry evah by any reasonable standards.\0";
  • C編譯器將自動連接兩個“相鄰”字符串,就好像它們是一個字符串一樣,它們之間沒有 NUL字符。 我把它們放在上面。
  • C編譯器會自動在任何字符串的末尾添加一個'\\0' 0'-在上例中的分號( ; )處。 這意味着該字符串實際上以兩個NUL字符結尾,而不是一個。

您可以在解析字符串“數組”時使用該事實來跟蹤您的位置-假設每個期望值的(子)字符串長度都超過零! 一旦遇到零長度(子)字符串,您就知道已經到達字符串“數組”的末尾。

我將這類字符串稱為ASCIIZZ字符串(所有結尾都帶有第二個NUL的ASCIIZ字符串)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM