簡體   English   中英

在函數中用memmove()連接字符串

[英]concatenate strings with memmove() in function

我想使用返回結果字符串的函數來連接兩個字符串。 會是這樣的:

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

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

    return StringResult;
}

我不知道這是否是一個好方法,因為我對內存管理知之甚少。 StringResult沒有定義的長度,我不確定在兩次記憶操作之后會發生什么。

我想StringResult將由函數本身清除,因為我不使用malloc(),對嗎?

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具有對象storage的概念。 對象的存儲確定其生存期,因為C不會被垃圾回收。 如果要創建新字符串,則必須為其保留存儲空間。 最簡單的方法是自動存儲,但這與聲明它的函數的范圍相關聯,因此在函數返回后,自動變量將不復存在。 另外,您可以使用靜態存儲,但是不能具有可變大小,並且對該函數的多次調用將使用同一存儲。 最后,您可以使用分配的存儲,這需要malloc()/calloc()/realloc()/free()

參見C11標准草案,第6.2.4 Storage durations of objects6.2.4 Storage durations of objects

這是使用現有的字符串命令而不是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指針的語法便利。

這是一個非常糟糕的主意,該功能不會神奇地進行“清理”。

您不能這樣做,這不是在C中實現字符串連接的有效方法。

在執行任何操作之前, 必須確保有足夠的可寫內存,因此通常必須調用malloc()

如果要避免動態分配,可以執行以下操作

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

為了完整memmove() ,假設使用memmove()只是一個想法,而不是一個要求, strcpy()strcat()是此處選擇的函數,因為它們是經過特殊設計的,可用於C字符串,即0終止的char -數組。

#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;
}

您必須使用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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM