【问题标题】:String arrays in CC中的字符串数组
【发布时间】:2011-01-22 19:54:00
【问题描述】:

我有一个字符串数组,当我遍历并打印它的元素时会给我带来意想不到的结果。

char currencies[][3] = {"EUR", "GBP", "USD", "JPY", "CNY"};

void show_currencies()
{
    int i;
    for(i=0; i<5; i++)
    {
        printf("%s - ", currencies[i]);
    }
}

当我调用 show_currencies() 时,我会在输出中得到这个。

EURGBPUSDJPYCNY - GBPUSDJPYCNY - USDJPYCNY - JPYCNY - CNY -

谁能解释一下这种行为。

谢谢

【问题讨论】:

  • 任何体面的编译器都应该为此给出错误或至少警告
  • @chapper, @martani:我手头没有 c 标准的副本,但我认为在这种情况下静默删除 NUL 字节是标准明确允许的。至少有一次,会有相当数量的代码使用这种技术来初始化固定大小的 char 数组,因为它比简单地逐个列出 char 值要简洁得多。

标签: c arrays string


【解决方案1】:

您缺少 nul 终止符,字符串实际上是 4 个字符长。然后每个字符串都覆盖前一个字符串的空终止符*。试试吧:

char currencies[][4] = {"EUR", "GBP", "USD", "JPY", "CNY"}; 

*正如 caf 所指出的,它不是“覆盖前一个字符串的空终止符”,因为空终止符永远不会复制到数组中。幸运的是,字符串在最后的“-”之后没有乱码输出。

【讨论】:

  • 是的 - 就是这样...您必须在数组中为空终止符以及实际内容留出空间...
  • ephemient,这不起作用(这是编译时错误)。您必须声明除最左侧维度之外的所有维度的大小(编译器必须知道一行有多长才能处理索引)。
  • 这是对的,除了每个字符串不是“覆盖前一个字符串的空终止符”——nul 终止符根本不会被写入,因为正在初始化的数组每个只有 3 个字符。 (最后一个数组恰好后面跟着一个终结符,这完全是侥幸)。
【解决方案2】:

你说错了。这将起作用。它只是让编译器设置一个指向 const-chars 的指针数组:

const char *currencies[] = {"EUR", "GBP", "USD", "JPY", "CNY"};

编辑:只要您为空值分配空间,就可以将其设为二维数组,就像 Charles Beattie 的回答一样。此外,根据 Christoph,指定字符为 const

【讨论】:

  • 实际上,两者都有效(如果您在原始代码中为终止零留出空间),但您的版本可能会更好,因为编译器将更容易优化它;不过,在这两种情况下,您都应该添加 const 限定符
  • 两个声明都不同。在 OP 的情况下,他声明了一个 double char 数组,而您的声明是一个 const char 指针数组。所以,在你的情况下,他不能修改数组的内容,我的意思是他不能做像 currency[0][1] = 'x';
  • 没错,伙计。看起来他并没有打算修改它。
【解决方案3】:

您没有字符串数组,而是字符数组。你可以使用:

char* currencies[] = {"EUR", "GBP", "USD", "JPY", "CNY"};  // untested

允许不同长度的字符串。

【讨论】:

    【解决方案4】:

    改变

    char currencies[][3]
    

    char currencies[][4]
    

    C 中的字符串以 NULL 结尾,以便于处理(打印、复制等)。 例如:char str[] = "ABC"; 将声明一个 4 字符的字符串,其中 \0 作为最后一个字符(索引 3)。

    作为提示,每当打印 char 数组时,您可能会得到意想不到的结果,您可能需要检查 char 数组是否以 NULL 终止。

    【讨论】:

      【解决方案5】:

      当然。 "EUR" 有四个字符长 - 三个用于字母,一个用于终止空字符。由于您明确指定了三字符数组,因此编译器正在截断,因此您的数据被串在一起。您很幸运,数组末尾显然有一个零字符,否则您可能会得到各种垃圾。将您的声明更改为char currencies[][4]

      【讨论】:

        【解决方案6】:

        我的 C 已经很生锈了,但是试试看:

        char currencies[][3] = {"EUR\0", "GBP\0", "USD\0", "JPY\0", "CNY\0"};
        

        我只是想知道会发生什么

        【讨论】:

        • 编译器应该发出警告。
        • 当您的字符串长度为 5 个字符时也会发生同样的情况。 "EUR\0" is equiv {'E','U','R','\0','\0'}
        猜你喜欢
        • 2013-08-16
        • 2011-08-12
        • 1970-01-01
        • 1970-01-01
        • 2012-03-20
        • 2018-04-02
        • 2015-03-27
        • 1970-01-01
        相关资源
        最近更新 更多