gpt4 book ai didi

c - 寻找一种优雅的方式在 C 中声明带有字符串的结构体数组

转载 作者:行者123 更新时间:2023-11-30 16:45:33 25 4
gpt4 key购买 nike

我正在尝试做一些类似于我在 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 语言制作类似的东西。我知道我可以做这样的事情:

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++方式那样优雅和清晰。我的“使命”是制作或找到一个预编译器宏,使代码尽可能具有可读性。

有什么建议吗?

最佳答案

您当前的 C 代码是错误的,因为 &s_00 不是指向 const-char 的指针 (const char*),而是指向-pointer-to-const-char (const char**),因为 s_00 的类型为 const char[]。其他人也一样。因此,必须先解决这个问题,然后才能使其看起来整洁。

此外,您还可以将 const 丢弃,只有当您知道指向的内存最终不会被修改时,这才是“安全”的。如果您不需要修改您的 AT 命令/响应,那么它们实际上是恒定的,因此您可以简单地对相关结构成员使用 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* 文字写入结构成员新分配的内存
  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*)。

关于c - 寻找一种优雅的方式在 C 中声明带有字符串的结构体数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44087810/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com