在C++中如何容易地完成未终止的字符数组



很抱歉,如果这可以通过谷歌解决——我什么都找不到。

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中,这完全是你自己的注意事项。

相关内容

  • 没有找到相关文章

最新更新