很抱歉,如果这可以通过谷歌解决——我什么都找不到。
char foo[4] = "abcd";
在C++中无效(由于需要"\0"终止符),但IIRC在C中有效--正确吗?
我有一组结构,其中有大量的"固定长度"字符字段,这些字段将被填充为空白,而不是以"\0"结尾。我希望能够进行通常类型的结构初始化——你知道
mystruct bar = {17, "abcd", 0x18, "widget ", ...
但我在C++中做不到。我想一个解决方案是将所有像这样初始化的结构放入它们自己的C(而不是++)源模块中。我试图避免的丑陋而费力的解决方案是
mystruct bar = {17, {'a', 'b', 'c', 'd'}, 0x18, {'w', 'i', 'd', 'g', 'e', 't', ' ', ' '}, ...
有一个好的C++解决方案吗?一个聪明的宏,可以有效地让"abcd"是没有"\0"终止符的char[4]?
谢谢,Charles
为结构提供一个构造函数,该构造函数接受大于所需大小1的char数组,并在复制它们时忽略终止字符。
bar::bar(int, char const(&)[5], int, char const(&)[9], ...)
或者,根据您的文档,您可以将参数设为char const*
,并信任用户传递正确大小的数组。如果你不想或不能向结构中添加任何内容,那么只需创建一个具有相同参数的函数,并返回一个参数(RVO应该消除额外的复制)。
您可以使用一个宏来完成这项工作:
#define MACRO_GET_1(str, i)
(sizeof(str) > (i) ? str[(i)] : 0)
#define MACRO_GET_4(str, i)
MACRO_GET_1(str, i+0),
MACRO_GET_1(str, i+1),
MACRO_GET_1(str, i+2),
MACRO_GET_1(str, i+3)
#define MACRO_GET_STR(str) MACRO_GET_4(str, 0)
struct mystruct {
char foo[4];
};
int main() {
mystruct obj{ MACRO_GET_STR("abcd") };
const char* str = "abcd";
std::cout << memcmp(obj.foo, str, 4); // 0
return 0;
}
示例
此代码基于此解决方案,并且它也很容易扩展。
无论如何,不久前有一个提案可能从未达到标准。有一些补丁可以将字符串文字转换为可变字符包。
我认为它将作为uint8数组(或编译器支持的任何数组)工作。只是永远不要认为它是一根绳子,因为它不是。分配一个额外的字符并初始化为零(通常是自动的)更安全。最好还是使用STL组件,除非有充分的理由做其他事情。
C++不是C。在C++中,编译器试图保护您的安全。在C中,这完全是你自己的注意事项。