2014-02-28 27 views
2

我有一個賦值,用戶將在運行時指定他們想要創建的struct的類型。在運行時創建一個特定的struct c

例如,可以說,用戶輸入:

名稱:焦[50],地址:炭[50]及年齡:整數

然後我的程序將不得不創建一個包含這一個struct 3種類型的變量。請注意,用戶可以爲結構指定儘可能多的變量,只將它們限制爲char和int。

我的代碼應該如何創建上面指定的結構?

這僅適用於c編程語言!

+1

C是一個靜態類型語言;你的程序需要實現一個解釋器(最低限度)或者一個完整的編譯器。 –

+0

@ElliottFrisch實際上,它沒有強大的打字,但是是一種靜態打字。這些是不同的事情。根據你的意見,我同意:我不認爲他可以用簡單的方法做到這一點。 – Mauren

+2

你可能並不是真的指'struct'。但是,您可以創建一個* dictionary *或* associative容器*,它允許您將屬性關聯到字段名稱。用戶在運行時指定的內容有時稱爲* schema *。 – jxh

回答

2

一個變量有3個字段: 1)type,2)name,3)地址。 你shuold創建一個包含這3個結構的數組,這個結構的陣列將是你想要什麼

您的結構可能是這樣的:

typedef enum _Type{T_INT,T_STRING}Type; 
typedef struct _var{ 
    Type type; 
    char* name; 
    union {int n; char* str;} data; 
}var; 

typedef struct _Struct{ 
    int count; 
    var* array; 
} Struct; 

當你輸入,你需要建立Struct根據它。 名的:char [50],地址:炭[50]及年齡:整數

Struct *s = malloc(sizeof(Struct)); 
s->count = 3;//count of fields in the input 
s->array = malloc(s->count*sizeof(var)); 
//you really should do it in a loop, after parsed the input... 
for(i=0;i<s->count;i++){ 
    s->array[i].name = strdup(parsedname);//"name", "address", "age" 
    s->array[i].type = strcmp(parsedtype,"int")?T_STRING: T_INT; 
    //for string you need to alloc memory for string... 
    if(s->array[i].type == T_STRING) 
    s->array[i].data.str=malloc(50 /*the size you've got*/); 
    //not need to alloc memory for the int 
} 

當您完成別忘了釋放mallocs:

for(i=0;i<s->count;i++){ 
free(s-array[i].name); 
if(s->array[i].type == T_STRING) 
    free(s->array[1].data.str); 
} 
free(s->array); 
free(s); 

你還需要一個方法來填充結構和打印,等等...

0

「唯一的限制他們爲char和int」

所以,你可以創建普通的數據類型(結構),保持節點與名稱列表,並char *,以及具有name和int的節點列表。 在每個新輸入中,只需填充所需數量的char *和int節點即可。

要訪問此類數據結構的字段,您需要遍歷列表。 如果您需要效率,您可以將列表替換爲映射(關聯數組)。你需要自己實現它,就像你在C上一樣。

1

我一直在想這個,因爲我正在考慮爲一種語言編寫FFI實現。 (雖然我懷疑,根據你接受的答案,你的用例有些不同)。

正如所指出的那樣,結構只能在編譯時生成,但這主要也是C語言的一個特性,可以啓用類型檢查,因此可以強制執行類型安全。

在運行時,您仍然可以將內存中的區域作爲原始字節進行操作。您只需根據所聲明的數據類型的各個組件知道長度和偏移量,並相應地對其進行管理。

我從查看Ruby FFI庫是如何實現的中挑選出來的。以下是他們的文檔:

當您調用Struct。新的,它分配一個「內部字節」值得的 然後。然後,當你做一個設置,如struct [:member] = 3, 那個結構中的位就設置好了。反過來也是 爲真; x = struct [:member]會從原始內存中讀取數據(並且將其翻譯爲紅寶石對象),每次訪問時都會如此。內存是 「清零」,當它首次分配時,除非你傳遞自己的 指針或指定它不清除內存(附加註釋)。如果你 傳遞它指針,它基本上使用它作爲它的基地,而不是 分配任何東西。

https://github.com/ffi/ffi/wiki/Structs#when-allocated