2017-05-20 3 views
0

私は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} 
}; 

私は、私はこのようsometringないことができることを知っているC. に似た何かを作るしようとしている:

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++の方法として、エレガントかつ明確ではありません。 私の "使命"は、できるだけ多くのコードを読みやすくするプリコンパイラマクロを作成または見つけることです。

提案がありますか?そのまま、&s_00ポインタツーCONST-CHAR(const char*)が、ポインタへのポインタツーCONST-CHAR(const char**)ではない、ためs_00があるため

答えて

0

現在のCコードは、間違っていますタイプ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()
  2. strncpy()構造体部材の新しく割り当てられたメモリにconst char* literall第一メモリの/ calloc()適量
  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

あなたのお返事ありがとうございます。 これは良い方法ですが、私のせいで、私は数kbのRAMしか持たないアームプロセッサのコードを書いているとは言及していません。 これは、大量のRAMを持つシステム(例えば、pcやlinuxを実行するボード)に適しています。 私の場合、mallocの使用はあまり良くありません。最良の方法は、マイクロプロセッサのフラッシュメモリに文字列を直接書き込ませ、必要な場合にのみRAMバッファにmemcpyを作成することです。これは、実行時に文字列をRAM上に置く関数ではなく、プリプロセッサマクロを使用する理由です。 – Katte

関連する問題