寻找一种优雅的方法来声明C中带有字符串的结构数组 我尝试做一些像我在C++中用QT做的事情,在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中带有字符串的结构数组 我尝试做一些像我在C++中用QT做的事情,在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,arrays,string,coding-style,C,Arrays,String,Coding Style,我正在尝试用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

我正在尝试用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},
    ....
};
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++那样优雅和清晰。 我的“任务”是制作或找到一个预编译器宏,使代码尽可能可读


有什么建议吗?

您当前的C代码是错误的,因为它不是指向常量字符(
const char*
)的指针,而是指向常量字符(
const char**
)的指针,因为
s_00
的类型是
const char[]
。其他的也一样。因此,在使其看起来整洁之前,必须先对其进行修复

此外,您还可以丢弃
常量
,只有当您知道指向的内存最终不会被修改时,该常量才是“安全的”。如果您不需要修改AT命令/repsonse,那么它们实际上是常量,因此您可以简单地对整个相关结构成员使用
const char*
,并在任何地方使用文本。到目前为止,最简单的解决方案是,您的代码如下所示:

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},
    ....
};
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++代码可能也没有工作),你需要做一些事情:

  • malloc()
  • strncpy()
  • 完成后,请确保再次释放该内存
  • 给出一个玩具示例,说明如何实现该功能:

    #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;
    }
    
    #包括
    #包括
    #包括
    结构Foo
    {
    字符*数据;
    };
    char*copy\u static\u字符串(const char*src,size\t sz)
    {
    if(src)
    {
    char*dst=malloc(sz);
    返回dst?strncpy(dst、src、sz):空;
    }
    其他的
    {
    返回NULL;
    }
    }
    #定义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,别忘了!
    免费(foo.data);//也别忘了清理!
    返回0;
    }
    

    作为一个旁白:您的C++代码的工作原理是,QStult是一个具有复制-写语义(拆分)的容器,因此您可以安全地通过它<代码> const char */Cord>,QString将在需要时复制它。(因此,不会尝试写入原始的
    常量字符*
    )。

    对不起,我没有检查、控制或编译C代码。:)是我的错。但是谢谢你的提示,特别是给我指出C++代码中的错误。也许我没有正确地写问题,因为我的请求是寻找更好的和最清晰的方式来写C++中的这种C++代码,只是为了使它成为最可读的可能。@ USER 11804我给出了一个玩具的例子。谢谢你的回应。这是一个好方法,但是,我的错,我没有提到我正在为只有几kb内存的arm处理器编写代码。对于具有大量ram的系统,例如pc或运行linux的主板,这是一个很好的替代方案。在我的例子中,malloc的使用不是很好。最好是将字符串直接写在微处理器的闪存上,并仅在需要时向ram缓冲区提供一些内存。这就是为什么我想使用预处理器宏,而不是在运行时将字符串放在ram上的函数。