【问题标题】:Nicest syntax to initialise a char array with a string, ignoring the null terminator用字符串初始化 char 数组的最佳语法,忽略空终止符
【发布时间】:2013-01-01 11:16:25
【问题描述】:

我经常想做这样的事情:

unsigned char urlValid[66] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";

...或:

unsigned char listOfChar[4] = "abcd";

...也就是说,从字符串文字初始化字符数组并忽略该文字中的空终止符。非常方便,而且我可以做sizeof urlValid之类的事情并得到正确的答案。

但不幸的是它给出了错误initializer-string for array of chars is too long

有没有办法:

  • 关闭此特定事件的错误和警告(即,如果在初始化 char 数组时没有空终止符的空间)
  • 做得更好,保持便利性和可读性?

【问题讨论】:

  • std::string 怎么样?
  • @David 我主要用 C 编写代码,有什么替代方案吗?
  • 如果这是 C,则删除 C++ 标签。
  • 等等,你想在 C++ 项目中使用 C?你的队友会恨你的……
  • @Alec,您是否知道 C 和 C++ 是不同的语言,它们“偶然”共享某些语法和名称中的一个字符?

标签: c syntax coding-style


【解决方案1】:

好吧,在 C++ 中,您应该始终使用 std::string。它很方便,不容易发生内存泄漏等。

但是,您可以在不指定大小的情况下初始化数组:

char urlValid[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";

这是可行的,因为编译器可以从字符串文字中推断出正确的大小。另一个优点是,如果文字发生变化,您不必更改大小。

编辑:不应将unsigned char 用于字符串。

【讨论】:

  • 添加了一个空终止符,这使得sizeof urlValid 返回67
  • @Alec 看,你为什么这么担心终止 NUL?这就是字符串在 C 中的工作方式。你应该习惯它。
  • 可能是因为他想要一个字符数组而不是字符串,@H2CO3。
  • 为什么要投反对票?如果字符串没有终止零,那么使用strcpy 等标准函数将很难处理该字符串。
  • 我想这不应该作为字符串使用。它看起来更像是一个查找数组或其他东西,尽管我会以不同的方式实现这样的查找
【解决方案2】:

您将问题标记为 C 和 C++。实际上,在 C 语言中,您不会收到此错误。相反,终止零根本不会包含在数组中。 IE。在 C 中,它完全按照您希望的方式工作。

在 C++ 中,您确实会得到错误。在 C++ 中,您可能必须容纳终止零并记住从 sizeof 的结果中减去 1。

另请注意,正如@Daniel Fischer 在 cmets 中建议的那样,您可以将定义与初始化“分离”

char urlValid[66]; 
memcpy(urlValid, "ab...", sizeof urlValid);

从而有效地在 C++ 中模拟 C 语言的行为。

【讨论】:

  • “根本不包括终止零”。这太有趣了。可以给我参考吗?
  • @Nawaz 6.7.9 (14) "一个字符类型的数组可以由一个字符串字面量或 UTF-8 字串字面量来初始化,可选用大括号括起来。字符串字面量的连续字节(包括终止空字符如果有空间或数组大小未知)初始化数组的元素。"
  • @Nawaz:在 C99 的 6.7.8/14 中。 “一个字符类型的数组可以由一个字符串字面量初始化,可选地用大括号括起来。字符串字面量的连续字符(如果有空间或数组大小未知,则包括终止的空字符)初始化阵列。”注意“如果有空间”部分。这一直是 C 和 C++ 的区别之一。
  • 在 C++ 中,他也可以unsigned char urlValid[66]; memcpy(urlValid, "ab...", sizeof urlValid);。这是否比 0 终止符更方便由 OP 决定。
【解决方案3】:

有两个简单的解决方案。

  1. 您可以像这样在数组中添加一个额外的元素:

    unsigned char urlValid[67] = 
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
    
  2. 或者忽略数组的大小:

    unsigned char urlValid[] =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
    

【讨论】:

  • OP 想要的恰恰相反。他想忽略尾随的 \0。
【解决方案4】:

用实际的字符数组初始化?

char urlValid[] = {'a','b','c','d','e','f',...};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多