c - C中任意长度的字符串

标签 c string

我需要对字符串进行一些操作(比如在某些地方添加字母)。我不知道它的大小是多少,这取决于输入。

如何在不指定大小的情况下定义字符串?我希望它适应我放入的任何内容。

为什么我不能将一个空的 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。 .

为什么不能定义大小未知的字符串

正如我已经写过的,字符串是字符数组的一部分。每个数组必须具有固定大小。您可以只使用它的一部分(有效地使其更小),但它必须被分配并且分配器( malloccalloc )需要知道需要多少内存。

如果您使用的数组大于分配的数组,您的程序可能会因 segfault 而崩溃。在更好的情况下。如果你非常不幸,你的程序不会崩溃,只会使用数组后面的那部分内存,产生奇怪的结果。

从 C99 开始,如果数组长度可以是 inferred from initializer,则可以省略它: char w[] = "Hello";char w[6] = "Hello"; 的结果相同。但是,这对您没有帮助,因为您在编译时指定了初始化程序,并且需要在运行时动态更改字符串长度。

如何模拟任意长度的字符串

要处理无限长度的字符串,您可以创建一个固定长度的数组,每次它的长度太短时,分配一个两倍长的新数组并将原始内容复制到新数组中。 (和 free 旧的。)您可以使用 realloc为您完成这项工作,当阵列不需要移动并且可以就地加长时,还有更高速度的额外好处。

关于c - C中任意长度的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20918341/

相关文章:

java - 以这种格式从字符串中解析日期 : dd/MM/yyyy [to dd/MM/yyyy]

javascript - 如何操作数组中的字符串

c - 如何调试被覆盖的指针?

java - 如何在 Java ME 中将 double 转换为字符串

c - 8 个 6 位单元的 48 位字符串 : how to get middle 4 bits of each unit quickly

c - 如何使用递归函数计算 C 中矩阵的行列式

android - 如何在android studio的xml字符串文件中放置 "&"

php - 连接参数中的字符串 (php)

c++ - 为什么对于来自客户端的每条写入消息,此程序都会在 C/C++ 中创建一个新进程?

c++ - 如何将二进制字符串转换为整数字符串