用Malloc连接两个字符串

时间:2019-01-08 21:56:32

标签: c

我一直在研究初学者C的问题,以尝试学习C的基础知识。我注意到下面的问题将从最后一个字符串起飞的索引开始,并将完成该字符串,但是我正在尝试要做的就是将两个字符串连接在一起。

有人能指出我正确的方向吗?我正在尝试不重新分配学习xp而这样做。

char *string_dup(char *src)
{
  int len = strlen(src);
  char *src2 = malloc(len + 1);
  int i;
  for(i = 0; i < len; i++){
    *(src2 + i) = *(src + i);
  }
  *(src2 + len )='\0';
  return src2;
}

void *resize_memory(void *ptr, int old_size, int new_size)
{
    char *d = (char*)ptr;
    d = malloc(new_size);
}


char *url = string_dup("http://");
char *path = string_dup("website.com/");
int url_length = string_length(url);
int path_length = string_length(path);

int new_length = url_length - 1 + path_length;
char *new_url = resize_memory(url, url_length, new_length);
char *p = new_url + url_length;


while (*path != '\0') {
    *p = *path;
    p++;
    path++;
}

printf("Full path string: %s\n", new_url);

3 个答案:

答案 0 :(得分:2)

OP的代码出现问题:

大小错误

假设string_length()就像strlen()

// int new_length = url_length - 1 + path_length;
int new_length = url_length + 1 + path_length;

调整大小无效

void *resize_memory(void *ptr, int old_size, int new_size) {
    char *d = (char*)ptr; // assign `d`
    d = malloc(new_size); // Why re-assigned `d`???
    // No use of old_size, new_size
    // No copying of existing data 
    // No freeing of old allocation  
}

我希望类似

// return failure status
bool resize_memory(void **ptr_addr, size_t old_size, size_t new_size) {
  void *new_ptr = NULL;
  if (new_size > 0) {
    new_ptr = malloc(new_size);
    if (new_ptr) {  // Out of memory, leave *ptr_addr alone
      return true;
    }
    size_t min_size = old_size < new_size ? old_size : new_size;
    memcpy(new_ptr, *ptr_addr, min_size);
  }
  free(*ptr_addr);
  *ptr_addr = new_ptr;  
  return false;
}

如何通过分配来连接带有realloc()的字符串。

  1. 找到长度。
  2. 分配内存。
  3. 如果成功,则复制第一个然后是第二个字符串。附加\ 0。

示例代码:

// s1, s2 may be NULL.  A NULL is treated as if ""
char *JoinStrings(const char *s1, const char *s2) {
  size_t len1 = s1 ? strlen(s1) : 0;
  size_t len2 = s2 ? strlen(s2) : 0;
  char *joined = malloc(len1 + len2 + 1);
  if (joined) {
    memcpy(joined, s1, len1);
    memcpy(joined + len1, s2, len2);
    joined[len1 + len2] = '\0';
  }
  return joined;
}

或通过snprintf()

char *JoinStrings(const char *s1, const char *s2) {
  size_t sz = (s1 ? strlen(s1) : 0) + (s2 ? strlen(s2) : 0) + 1;
  char *joined = malloc(sz);
  if (joined) {
    int len = snprintf(joined, sz, "%s%s", s1, s2);
    assert(len >= 0 && (unsigned) len < sz);  // Failure is very unexpected here.
  }
  return joined;
}

要像(* s1)+ = s2那样串联

// *s1 is a prior allocated string, or NULL
 void ConcatenateString(char **s1, const char *s2) {
  char *joined = JoinStrings(*s1, s2);
  free(*s1);
  *s1 = joined;
}

答案 1 :(得分:0)

尝试类似

char *url = string_dup("http://");
char *path = string_dup("website.com/");
size_t sTotal = strlen(url) + strlen(path) + 1u;
char *pStr = malloc(sTotal);
snprintf(pStr, sTotal, "%s%s", url, path);
free(url);
free(path);

答案 2 :(得分:0)

我玩了一段时间您的代码,然后提出了这个解决方案。这样,您就可以摆脱该string_dup()函数,并创建一个可以分配/分配新字符串并为现有字符串添加更多数据的函数。

int
append_string(char **append_to, char *append_this) {
    char    *tmp;

    // You might want to check that append_this is not
    // NULL...

    if (*append_to == NULL) {
        *append_to = malloc(strlen(append_this) + 1);
        strcpy(*append_to, append_this);
    }
    else {
        // Some data already exists on the append_to buffer...
        //
        // If you want to only use malloc() then make a temporary
        // storage area and copy the append_to string there
        //
        if ((tmp = malloc(strlen(*append_to) + 1)) == NULL)
            return -1;
        strcpy(tmp, *append_to);

        // Free up and re-allocate append_to.
        //
        free(*append_to);
        *append_to = malloc(strlen(tmp) + strlen(append_this) + 1);

        if (! append_to) {
            fprintf(stderr, "Malloc error...");
            exit(EXIT_FAILURE);
        }

        // Do it with realloc
        //
        // No temporary buffer required:
        //
        //      *append_to = realloc(
        //          *append_to,
        //          (strlen(append_to) + strlen(*append_this) + 1)
        //      );
        //      if (! eppend_to) ...realloc error

        // Copy the data to the buffer and clean up.
        //
        sprintf(*append_to, "%s%s", tmp, append_this);
        free(tmp);
    }
}


/* In your main() or whatever... */

    char *url = NULL;
    char *path = NULL;

    // Since url and path are both NULL the
    // append string function will act like
    // your string_dup() function...
    append_string(&url, "http://");
    append_string(&path, "website.com/");

    // And not that url is not null it will be
    // resized and the path appended.
    append_string(&url, path);

    fprintf(stdout, "URL: %s\n", url);

    // Some housekeeping....
    if (url) free(url);
    if (path) free(path);
}

希望它有用,我知道它与您最初拥有的还相去甚远,但我想我会继续玩下去!