1

我想使用返回结果字符串的函数连接两个字符串。它会是这样的:

char *String_Concat (char *String_1, char *String_2)
{
    char *StringResult;

    //memmove String_1 to StringResult
    //memmove String_2 to StringResult

    return StringResult;
}

我想知道这是否是一种好方法,因为我对内存管理知之甚少。StringResult 没有定义的长度,我不确定两次 memmove 操作后会发生什么。

我想 StringResult 将由函数本身清理,因为我不使用 malloc(),对吗?

4

6 回答 6

4
char *String_Concat (char *String_1, char *String_2)
{
    size_t len1 = strlen(String_1);
    size_t len2 = strlen(String_2);
    char *StringResult = malloc(len1+len2+1);
    //might want to check for malloc-error...
    memcpy(StringResult, String_1, len1);
    memcpy(&StringResult[len1], String_2, len2+1);
    return StringResult;
}

所以,C 有storagefor 对象的概念。对象的存储决定了它的生命周期,因为 C 不是垃圾回收的。如果要创建新字符串,则必须为其保留存储空间。最简单的方法是自动存储,但这与声明它的函数的范围相关,因此自动变量在函数返回后不再存在。或者,您可以使用静态存储,但它不能具有可变大小,并且对该函数的多次调用将使用相同的存储。最后,您可以使用分配的存储空间,这需要malloc()/calloc()/realloc()/free().

见 C11 草案标准,部分6.2.4 Storage durations of objects

于 2015-01-12T15:10:48.710 回答
2

这是我将如何处理它,使用现有的字符串命令而不是 memcpy。我假设你想要像 strcat 这样不影响源字符串的东西。

char* string_concat(char *dest, const char* string1, const char* string2)
{
   strcpy(dest, string1);
   strcat(dest, string2);
   return dest;
}

要使用它,您需要传入一个指向要存储结果的缓冲区的指针。您可以使用 malloc 将其设置为所需的大小。完成后释放它。

char *str1 = "abc";
char *str2 = "def";
size_t len = strlen(str1) + strlen(str2);
char *newstr = malloc(len + 1);
string_concat(newstr, str1, str2);
printf("%s\n", newstr);
free(newstr);

在不分配内存的情况下根本无法处理任意长度的字符串,因此除非您使用具有固定长度的字符数组,否则您将无法使用 malloc/free。如果您想抽象决定分配多少缓冲区的逻辑,您可以执行以下操作:

size_t string_concat(char* dest, char* string1, char* string2)
{
   if(!dest)
   {
      return strlen(string1) + strlen(string2) + 1;
   }
   strcpy(dest, string1);
   strcat(dest, string2);
   return 0;
}

然后你可以像这样询问它分配多少:

char* newstr = malloc(string_concat(0, str1, str2));

但是你失去了它返回一个指向 dest 的指针的语法便利。

于 2015-01-12T15:32:53.517 回答
0

这是一个非常糟糕的主意,并且该功能不会神奇地发生“清洁”。

你不能这样做,这不是在 C 中实现字符串连接的有效方法。

在做任何事情之前你必须确保有足够的可写内存,所以通常你必须调用malloc().

于 2015-01-12T15:11:14.977 回答
0

如果你想避免动态分配,你可以做类似的事情

int main( int argc, char **argv)
{
    char        String_1[8] = "Exa";
    /*                   ^ enough space for Example\0 */
    const char *String_2    = "mple";

    printf("%s\n", strcat(String_1, String_2));

    return 0;
}
于 2015-01-12T15:12:48.697 回答
0

为了完整起见,假设 usingmemmove()只是一个想法,而不是要求,strcpy()strcat()是这里选择的函数,因为它们是专门为处理 C-“字符串”,即0-terminated char-arrays 而设计的。

#include  <stdlib.h> /* for malloc() */
#include  <string.h> /* for strcpy() and strcat() */
#include  <errno.h> /* for errno and EINVAL */

char * stralloc_and_cat(const char * s1, const char * s2)
{ 
  char * s = NULL;

  if ((NULL == s1) || (NULL == s2))
  {
    errno = EINVAL;
  }
  else 
  {
    if (NULL != (s = malloc(strlen(s1) + strlen(s2) + 1)))
    {
      strcpy(s, s1);
      strcat(s, s2);
    }
  }

  return s;
} 

并这样称呼它:

#include  <stdlib.h>
#include  <stdio.h>

char * stralloc_and_cat(const char * s1, const char * s2);

int main(void)
{
  char * s1 = "hello ";
  char * s2 = "world";

  char s = stralloc_and_cat(s1, s2);
  if (NULL == s)
  {
    perror("stralloc_and_cat() failed");
  }
  else
  {
    printf("%s\n", s);

    free(s);
  }

  return 0;
}
于 2015-01-12T15:31:27.757 回答
0

您必须使用malloc()为生成的 concat 字符串动态分配一些内存。
在这种情况下,调用者负责调用free()以释放返回的字符串指针指向的内存。

另一种方法是设计一个函数,该函数期望指向调用者分配的目标缓冲区的指针,该缓冲区大到足以存储总的结果字符串。

在第一个选项之后,您可以考虑这样的代码(在 Ideone 上直播):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Concatenates string1 and string2.
// Returns the concatenated (string1+string2), or NULL on errors.
// NOTE: Memory for the returned string is allocated with malloc() 
// by the function, so the caller is responsible to release it with
// a call to free().
char *StringConcat(const char *string1, const char *string2)
{
    char *stringResult;
    size_t len1;
    size_t len2;

    // Check for NULL pointers...
    // (Return NULL, or whatever your design is...)
    if (string1 == NULL || string2 == NULL) {
        return NULL;
    }

    len1 = strlen(string1);
    len2 = strlen(string2);

    // +1 for terminating NUL ('\0')
    stringResult = malloc(len1 + len2 + 1);
    if (stringResult == NULL) {
        return NULL; // Allocation error
    }

    // Copy characters from first string    
    // (exclduing the terminating NUL --> len1)
    memcpy(stringResult, string1, len1);

    // Copy characters from second string
    // (including the terminating NUL --> len2+1)
    memcpy(stringResult + len1, string2, len2+1);

    // Return destination string pointer to the caller.
    // NOTE: Memory must be freed by the caller calling free().
    return stringResult;
}


// *** TEST ***
int main(void)
{
    // Test the function
    char * str = StringConcat("Hello ", "World");

    // Print the resulting string
    printf("%s\n", str);

    // Don't forget to free() memory allocatd by the concat function
    free(str);

    // All right
    return 0;
}
于 2015-01-12T15:35:45.447 回答