使用snprintf在开头追加

时间:2013-01-30 23:43:43

标签: c

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

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

所以我有类似的东西

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

这不管是第一个还是第二个的内容,或者它们是否需要特殊考虑(以\ 0或任何内容开头或结尾)?

第一个和第二个都是动态分配的u_char数组。

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

3 个答案:

答案 0 :(得分:3)

您应该分配strlen(first) + strlen(second) + 1

  

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

然后它们不是C字符串,并且您没有使用像strlen这样的字符串函数的业务。您应该使用memcpy代替snprintf

答案 1 :(得分:1)

  

这是否可以在第一或第二的内容中起作用,或者它们是否需要特殊考虑(以\ 0或任何内容开头或结尾)?

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

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

字符串

如果这些是正确的NUL终止的C字符串,那么:

  1. 不要忘记为'\0'字符添加空格。
  2. 不需要演员(u_char *)
  3. 这甚至可以编译吗? snprintf的第二个参数应该是要写入的字节数 size
  4. 编译器还应该抱怨传递u_char *而不是char *
  5. 鉴于这一切,我将代码编写为:

    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);
    

    二进制数据

    如果这些是二进制数据,那么您就不能使用strlensprintf等字符串函数。你必须重写代码才能避免它们。

    没有自动的方法来计算字节数组的长度。这是你必须跟踪自己的信息。

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

    使用memcpymemmove复制任意字节。

    if (newStorage == NULL) {
        /* handle error */
    }
    else {
        memcpy(newStorage,             first,  firstSize);
        memcpy(newStorage + firstSize, second, secondSize);
    }
    

答案 2 :(得分:0)

有很多方法可以做到这一点,其中一个是这样的。在您的情况下,问题是您没有在新分配的数组中允许空格终止NULL。

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