1

我有一个用 malloc 创建的数组 u_char *,它包含一个字符串。它实际上大于字符串的长度。

我想使用 snprintf() 将另一个数组附加到此数组的开头,并存储在另一个数组中。

所以我有这样的东西

u_char * newstorage = (u_char *)malloc(strlen(first) + strlen(second));
snprintf(newstorage, "%s%s", first, second);

无论第一还是第二的内容,这项工作是否应该起作用,或者他们是否需要有特殊的考虑(以 \0 或任何内容开始或结束)?

first 和 second 都是动态分配的 u_char 数组。

问题是最后的newstorage 似乎不包含完整的字符串,而只是它应该包含的内容的一个子集。如果第一个或第二个在字符串中间包含错误的 \0 或其他什么,会有任何问题吗?(很有可能,因为我无法控制它们)。

4

3 回答 3

3

你应该分配strlen(first) + strlen(second) + 1.

如果第一个或第二个在字符串中间包含错误的 \0 或其他东西

那么它们就不是 C 字符串了,你也没有必要strlen在它们上面使用字符串函数。您应该使用memcpy而不是snprintf.

于 2013-01-30T23:46:05.830 回答
1

无论第一还是第二的内容,这是否都有效,还是需要特殊考虑(以 \0 或任何内容开头或结尾)?

您正在使用字符串函数,因此这些函数必须是正确的 C 字符串:即,它们必须以'\0'字符结尾,并且字符串中不能有任何其他 NUL。

如果这些实际上是二进制数据而不是字符串,那么您不能使用像strlen和这样的字符串函数sprintf。我想我会为这两种不同的情况写两个不同的答案。

字符串

如果这些是正确的以 NUL 结尾的 C 字符串,则:

  1. 不要忘记为'\0'字符包含空格。
  2. 演员表(u_char *)是不必要的。
  3. 这甚至可以编译吗?第二个参数snprintf应该是要写入的字节数。
  4. 编译器还应该抱怨传递 au_char *而不是 a char *

鉴于这一切,我将代码编写为:

size_t  size = strlen(first) + strlen(second) + 1;
u_char *str  = malloc(size);

if (str == NULL) {
    /* handle error */
}
else {
    snprintf((char *) str, size, "%s%s", first, second);
}

实际上,在这种情况下,您可以选择更简单sprintf的,因为您知道字符串总是合适的。

sprintf((char *) str, "%s%s", first, second);

二进制数据

如果这些是二进制数据,那么您不能使用像strlen和这样的字符串函数sprintf。您必须重写代码以避免它们。

没有自动方法可以确定字节数组的长度。这是您必须自己跟踪的信息。

size_t  firstSize  = /* ??? */; 
size_t  secondSize = /* ??? */; 
u_char *newStorage = malloc(firstSize + secondSize);

memcpy要在 use或周围复制任意字节memmove

if (newStorage == NULL) {
    /* handle error */
}
else {
    memcpy(newStorage,             first,  firstSize);
    memcpy(newStorage + firstSize, second, secondSize);
}
于 2013-01-30T23:48:43.130 回答
0

有很多方法可以做到这一点,这是其中之一。您的问题是您没有为新分配的数组中的终止 NULL 留出空间。

snprintf这种方式使用效率低下,我不确定这对您来说是否有问题。您可以同样分配一个新数组并用于strcpy连接您的数组。

于 2013-01-30T23:47:56.490 回答