2017-05-20 28 views
0

我想要做的事情就像我在C++中用QT所做的一樣,在C中。 這是C++代碼的一部分:尋找一個優雅的方式來聲明一個結構數組中的字符串C

typedef struct { 
    int  order; 
    int  type; 
    QString cmd; 
    QString res[2]; 
    double timeout; 
    int  exitAfterNChar; 
}atCmdList_t; 
atCmdList_t atCmdList[] = { 
    {0,0, "ATI", {"", ""}, 1, -1}, 
    {0,0, "AT+GSN", {"", ""}, 1, -1}, 
    {0,0, "AT+COPS?", {"+COPS: 0,0,\"vodafone IT\",2", ""}, 1, -1} 
}; 

我試圖在C. 類似的,我知道我能做到sometring是這樣的:

const char s_00[] = {""}; 
const char s_01[] = {"ATI"}; 
const char s_02[] = {"AT+GSN"}; 
const char s_03[] = {"AT+COPS?"}; 

typedef struct { 
    int  order; 
    int  type; 
    const char * cmd; 
    const char * res[2]; 
    double timeout; 
    int  exitAfterNChar; 
} atCmdList_t; 
atCmdList_t atCmdList[] = { 
    {0,0, s_01, {s_00, s_00}, 1, -1}, 
    {0,0, s_02, {s_00, s_00}, 1, -1}, 
    .... 
}; 

但這不是優雅,皎潔如C++的方式。 我的「使命」是製作或查找預編譯器宏,使代碼儘可能多地可讀。

有什麼建議嗎?

回答

0

您當前的C代碼是錯誤的,因爲,因爲它是&s_00不是指針給const-CHAR(const char*),但指針到指針到常量,字符(const char**),因爲s_00是類型const char[]。其他人也一樣。所以在使它看起來整齊之前必須修復。

此外,如果您知道所指向的內存畢竟不會被修改,那麼您只需將const轉換爲僅'安全'。如果你不需要修改你的AT命令/ repsonse,那麼它們實際上是不變的,所以你可以簡單地使用const char*作爲整個相關結構成員,並在任何地方使用文字。到目前爲止,最簡單的方法,你的代碼應該是這樣的:

typedef struct { 
    int  order; 
    int  type; 
    const char* cmd; 
    const char* res[2]; 
    double timeout; 
    int  exitAfterNChar; 
} atCmdList_t; 

atCmdList_t atCmdList[] = { 
    {0,0, "ATI", {"", ""}, 1, -1}, 
    {0,0, "AT+GSN", {"", ""}, 1, -1}, 
    {0,0, "AT+COPS?", {"+COPS: 0,0,\"vodafone IT\",2", ""}, 1, -1} 
}; 

如果需要對其進行修改(那麼你的C++代碼可能沒有正確或者工作過),你需要做一些涉及:

  1. malloc()/calloc()適當的存儲器第一
  2. strncpy()const char* literall到結構構件的新分配的存儲器量
  3. 完成後,請務必再次登錄free()

爲了讓你能如何實現一個玩具例子:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

struct Foo 
{ 
    char * data; 
}; 

char * copy_static_string(const char* src, size_t sz) 
{ 
    if(src) 
    { 
    char * dst = malloc(sz); 
    return dst ? strncpy(dst, src, sz) : NULL; 
    } 
    else 
    { 
    return NULL; 
    } 
} 

#define COPY_STATIC_STRING(x) (copy_static_string((x), sizeof(x))) 

int main() 
{ 
    struct Foo foo = { .data = COPY_STATIC_STRING("hello, world!") }; 
    printf("%s\n", foo.data); // check .data != NULL, don't forget! 
    free(foo.data); // don't forget to clean up, either! 
    return 0; 
} 

順便說一句:你的C++代碼「作品」是QString與寫入時複製語義的容器的原因(分離),所以你可以安全地通過它const char*和QString會在需要時複製它。 (因此不會嘗試寫入原始的const char*)。

+0

對不起,我沒有檢查,控制或編譯的C代碼。 :) 我的錯。 但是,特別感謝提示我指出了C++代碼中的錯誤。 也許我沒有正確地寫出這個問題,因爲我的要求是關於在C中編寫這種類型的C++代碼的更好和最清晰的方式,只是爲了使它成爲最可讀的可能。 – Katte

+0

@ user11804我已經給出了一個替代方案的玩具例子。 – user268396

+0

感謝您的回覆。 這是一個好方法,但是,我的錯,我沒有提到我正在爲arm處理器編寫只有幾kb內存的代碼。 這是一個很好的替代系統,有大量內存,例如pc或運行linux的主板。 在我的情況下,malloc的使用不太好。最好是讓字符串直接寫在微處理器的閃存上,並只在需要時纔將一些memcpy寫入RAM緩衝區。這就是爲什麼我想使用預處理器宏而不是在運行時將字符串放在RAM上的函數。 – Katte

相關問題