我正在尝试做一些类似我在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 ++那样优雅和清晰。 我的“使命”是创建或查找预编译器宏,使代码尽可能可读。
有什么建议吗?
答案 0 :(得分:0)
您当前的C代码是错误的,因为&s_00
不是指向const-char(const char*
)的指针,而是指针指向const-char的指针(const char**
),因为s_00
的类型为const char[]
。其他人也一样。所以必须先修复它才能使它看起来整洁。
此外,您将const
投放到了只有“安全”的地方。如果你知道指向内存的话毕竟不会被修改。如果你不需要修改你的AT命令/ repsonse,那么它们实际上是有效的,所以你可以简单地将const char*
用于相关的struct成员并在任何地方使用文字。到目前为止最简单的解决方案,您的代码将如下所示:
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()
/ calloc()
适当的内存量strncpy()
const char*
literall到新分配的struct成员内存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 ++代码工作的原因&#39;是QString
是一个具有写时复制语义(分离)的容器,因此您可以安全地传递它const char*
,QString将在需要时复制它。 (因此不会尝试写入原始const char*
)。