3

抱歉,如果这可以通过 Google 解决 - 我找不到任何东西。

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]?

谢谢,查尔斯

4

3 回答 3

1

为结构提供一个构造函数,该构造函数接受大小为 1 的 char 数组,大于您需要的大小,并在复制它们时忽略终止字符。

bar::bar(int, char const(&)[5], int, char const(&)[9], ...)

或者,您可以char const*根据您的文档制作参数并信任用户传递正确大小的数组。如果您不想或不能向结构添加任何内容,则只需创建一个具有相同参数的函数,该函数返回一个(RVO应该消除额外的复制)。

于 2014-10-28T16:38:29.890 回答
0

我认为它将作为一个 uint8 数组(或任何你的编译器支持的)工作。只是永远不要认为它是一个字符串,因为它不是。分配一个额外的字符并初始化为零(通常是自动的)要安全得多。最好还是使用 STL 组件,除非有很好的理由去做其他事情。

C++ 不是 C。在 C++ 中,编译器试图保证你的安全。在 C 中,这完全是您自己的监视。

于 2014-10-28T16:40:39.117 回答
0

你可以使用一个宏来完成这项工作:

#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;
}

Example

此代码基于此解决方案,并且也很容易扩展。

无论如何,前一段时间有一个提案可能从未达到标准。有一些补丁允许将字符串文字转换为可变字符包。

于 2014-10-28T16:45:13.453 回答