如何动态地向数组中添加字符?而不需要预先定义数组?

3

如果我想向字符数组中添加字符,必须按照以下方式进行:

#include <stdio.h>

int main() {
    int i;
    char characters[7] = "0000000";
    for (i = 0; i < 7; i++) {
        characters[i] = (char)('a' + i);
        if (i > 2) {
            break;
        }
    }

    for (i = 0; i < 7; i++) {
        printf("%c\n", characters[i]);
    }
    return 0;
}

为了避免打印任何奇怪的字符,我必须初始化数组,但这并不灵活。如何动态地向char数组添加字符?就像在Python中一样:
characters = []
characters.append(1)
...

1
“char characters[7] = "0000000";”无法编译(如果你很幸运),因为“0000000”是由8个字符组成的数组,包括字符串末尾的空指针。如果你真的想要一个由7个字符组成的数组,请使用“ char characters[7] = {'0','0','0','0','0','0','0'}";” - mattnz
@mattnz:在C语言中,char a[7] = "1234567";是完全没有问题的。我知道在C++中这是一个错误,但是这篇文章没有标记那种语言,因此你的评论是误导性的。 - pmg
3个回答

10

对于纯C语言来说,没有一个不丑陋的解决方案。

#include <stdio.h>

int main() {
    int i;
    size_t space = 1;                  // initial room for string
    char* characters = malloc(space);  // allocate
    for (i = 0; i < 7; i++) {
        characters[i] = (char)('a' + i);
        space++;                       // increment needed space by 1
        characters = realloc(characters, space); // allocate new space
        if (i > 2) {
            break;
        }
    }

    for (i = 0; i < 7; i++) {
        printf("%c\n", characters[i]);
    }
    return 0;
}

实际上,你要避免使用realloc,并且当然要分配比一个字节更大的内存块,甚至是指数级别的。但本质上这就是std::string等内部机制的运作方式:你需要一个计数器来计算当前大小,一个当前最大大小的变量(为了简单起见,这里总是当前大小+1),如果需要的空间超过当前最大大小,则需要重新分配。


3
你没有释放内存! - Chris Watts
3
主函数中的 return 隐式释放所有内存。 - Gunther Piez

4

当然可以动态添加字符:

quote char[100] = "The course of true love";
      strcat( quote, " never did run smooth.";

但只有当引用[]中有足够的空间来容纳附加的字符时才能这样做。或许你在问为什么在C语言中,你必须预先安排足够的字符存储空间,而在Python中,存储空间是动态分配的。这就是语言在197x年设计的方式。
C99确实允许动态分配存储空间:由系统在运行时分配的存储空间。在我看来,这是一个非常糟糕的错误。 C99


你为什么认为在 C99 中添加动态分配存储能力是一个糟糕的主意?我对此没有任何意见,只是好奇… - insumity
+1 - 感谢让我意识到C99又犯了一个错误。它并不是真正的C。 - Heath Hunnicutt
@equality -- 如果您不知道,C99中的动态分配内存称为“可变长度数组”或VLAs。仅我个人看法:(1)VLA是在堆栈上分配而不是堆上,这使得很容易因错误而不带警告地扩大堆栈。(2)'sizeof'不再需要产生常数; 我可以在运行时获取VLA的'sizeof'。这让我感到困惑和害怕。(3)因为C不再是C ++的子集——C ++中没有VLAs——我不能再使用C ++编译器编译/链接我的程序; 因此,很难将我的C程序移植到C ++。我同意@Heath Hunnicutt的观点:C99不是C。 - Pete Wilson

-3

除非您使用 链表 或其他自定义数据结构,否则无法实现。


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