C语言中的字符串数组

11

我有一个字符串的数组,当我遍历并打印它的元素时,它给出了意料之外的结果。

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 -

有人能解释这种行为吗。

谢谢


任何一个像样的编译器都应该对此给出错误或至少警告。 - chappar
1
@chapper,@martani:我手头没有C标准的副本,但我认为在这种情况下静默地丢弃NUL字节是标准明确允许的。至少在某个时候,会有相当数量的代码使用这种技术来初始化固定大小的char数组,因为它比逐一列出char值更简洁。 - Dale Hagglund
6个回答

14

你缺少了空字符终止符,导致字符串实际上是4个字符长。每个字符串都会覆盖前一个字符串的空字符终止符。尝试使用以下内容:

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

正如caf所指出的那样,它并没有“覆盖前一个字符串的空终止符”,因为空终止符从未复制到数组中。仅仅是偶然情况下,在最后一个“-”之后字符串没有混乱的输出。


是的 - 就是这样... 你必须在数组中为空终止符和实际内容留出空间... - Martin Milan
ephemient,那不行(这是编译时的错误)。你必须声明除最左边维度以外的所有维度的大小(编译器必须知道一行有多长才能处理索引)。 - Matthew Flaschen
1
这是正确的,除了每个字符串并没有“覆盖前一个字符串的空终止符” - 空终止符根本没有被写入,因为被初始化的数组只有3个字符。 (最后一个数组恰好跟随终止符完全是偶然的)。 - caf

8
您声明方式不正确。以下是正确的声明方式,这样可以使编译器设置一个指向常量字符的指针数组:
const char *currencies[] = {"EUR", "GBP", "USD", "JPY", "CNY"};

编辑:像Charles Beattie的回答一样,将其变为二维数组也可以,前提是你要为null分配空间。此外,根据Christoph的建议,指定字符为const


实际上,两种方法都可以(如果在原始代码中留出终止零的空间),但您的版本可能更好,因为编译器将更容易地优化它;在两种情况下,您都应该添加“const”限定符。 - Christoph
这两个声明是不同的。在 OP 的情况下,他声明了一个双字符数组,而你的声明是一个常量字符指针数组。因此,在你的情况下,他不能修改数组的内容,也就是说他不能做像 currencies[0][1] = 'x' 这样的操作。 - chappar
没错,chappar。他似乎并不打算对其进行修改。 - Matthew Flaschen

2

更改

char currencies[][3]

为了

char currencies[][4]

C语言中的字符串以NULL结尾,这使得它们的处理(如打印、复制等)更加容易。 例如:char str[] = "ABC"; 将声明一个由4个字符组成的字符串,其中\0是最后一个字符(索引为3)。

提示:当打印字符数组时出现意外结果时,您可能需要检查字符数组是否已以NULL结尾。


2

您没有一个字符串的数组,而是一个字符数组的数组。您可以使用以下方法:

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

允许不同长度的字符串。


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

0

我的 C 语言有点生疏,但是可以试试:

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

我只是好奇想知道会发生什么


1
编译器应该发出警告。 - ezpz
2
当您的字符串长度为5个字符时,同样会发生这种情况。"EUR\0"等同于{'E','U','R','\0','\0'} - Charles Beattie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接