我需要对字符串进行一些操作(比如在某些地方添加字母)。我不知道它的大小是多少,这取决于输入。
如何在不指定大小的情况下定义字符串?我希望它适应我放入的任何内容。
为什么我不能将一个空的 char *
传递给一个方法?编译器不允许这样做。
根据答案,我明白我不能创建无限大小的字符串。但是例如当我尝试创建 char arr[100]
而我的字符串长度只有 8 个字符时,当我打印 arr
时,我得到了比我想要的更多的字母。其中一些甚至不是字符串的一部分。这怎么可能?
最佳答案
简答
您不能定义大小未知的字符串。但是您可以在需要时使字符串越来越大。所有字符串和 I/O 函数都需要获得一个已分配的字符串才能使用,因此您必须稍微尝试一下分配并注意不要超过分配的容量。
然而,当你的字符串长度有一个恒定的上限时,只要分配那个长度的字符串就安全了。调整大小比较复杂,因此如果不需要,请避免使用它。
什么是C中的字符串
字符串是字符数组的一部分,以\0
结束。字符串函数在遇到第一个 \0
字符时停止读取数组。请记住 strlen
返回第一个 \0
之前 的字符数,因此即使数组在第一个 \0
之后立即结束,字符串长度也严格小于比底层数组长度。具体来说,在这种情况下,数组长度为 strlen + 1
。这在分配字符串时很重要;始终为终止 \0
分配空间!
例如
char w[7] = "Hello";
与
相同char w[7] = {'H', 'e', 'l', 'l', 'o', '\0', '\0'};
当用作字符串时,第一个 \0
是字符串的结尾,之后的任何内容都将被忽略(不被字符串函数读取)。即使您用可打印字符重写示例 char 数组的最后一个元素(例如 w[6] = '!';
导致 {'H', 'e', ' l', 'l', 'o', '\0', '!'}
), puts(w);
将打印 Hello
(不是你好!
或任何类似的东西)。
当像处理 char 数组一样处理字符串时,请务必始终在其末尾包含 \0
,否则在字符串函数读取数组后可能会出现未分配的内存,这会导致 segfault。 .
为什么不能定义大小未知的字符串
正如我已经写过的,字符串是字符数组的一部分。每个数组必须具有固定大小。您可以只使用它的一部分(有效地使其更小),但它必须被分配并且分配器( malloc
, calloc
)需要知道需要多少内存。
如果您使用的数组大于分配的数组,您的程序可能会因 segfault 而崩溃。在更好的情况下。如果你非常不幸,你的程序不会崩溃,只会使用数组后面的那部分内存,产生奇怪的结果。
从 C99 开始,如果数组长度可以是 inferred from initializer,则可以省略它: char w[] = "Hello";
与 char w[6] = "Hello";
的结果相同。但是,这对您没有帮助,因为您在编译时指定了初始化程序,并且需要在运行时动态更改字符串长度。
如何模拟任意长度的字符串
要处理无限长度的字符串,您可以创建一个固定长度的数组,每次它的长度太短时,分配一个两倍长的新数组并将原始内容复制到新数组中。 (和 free 旧的。)您可以使用 realloc
为您完成这项工作,当阵列不需要移动并且可以就地加长时,还有更高速度的额外好处。
关于c - C中任意长度的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20918341/