代码之家  ›  专栏  ›  技术社区  ›  Paradox

字符串指针的C strcpy数组

  •  2
  • Paradox  · 技术社区  · 8 年前

    我有一个这样声明的数组:

    char *array[4];
    

    它由一个带字符串的不同函数填充,即[“一”、“二”、“三”、“四”]。

    我的目标是将这个数组复制到一个新数组中,不包括最后两个元素,因此新的_数组将包含[“one”,“two”]。

    这是我迄今为止尝试过的:

    int *new_array[2];
    
    for (int i = 0; i < 2; i++){
        strncpy(new_array[i], array[i], strlen(array[i]));
    }
    

    但收到以下警告:

    warning: passing argument 1 of ‘strncpy’ from incompatible pointer type [-Wincompatible-pointer-types]
    
    note: expected ‘char * restrict’ but argument is of type ‘int *’
    

    外部字符*strncpy(字符*\uu限制\uu目标,

    3 回复  |  直到 8 年前
        1
  •  4
  •   Paradox    8 年前

    你的代码有一些问题

    首先,它声明了一个整数指针数组(因此出现警告),然后这些指针没有初始化。 strncpy 不是合适的调用函数(即使内存已初始化,也不会为null终止字符串),您需要 strdup 正确的分配和;副本:

    char *new_array[2];
    
    for (int i = 0; i < 2; i++){
        new_array[i] = strdup(array[i]);
    }
    

    strdup标准 可能不可用。如果你是那样的话,就用 new_array[i] = malloc(strlen(array[i]+1)); 然后 strcpy(new_array[i],array[i]); )

    这两种方法都分配动态内存和需求 free 当不再使用时。

    但是如果你只想存储指针,例如因为 array 包含 字面量 您不打算修改字符串,只需复制指针即可:

    new_array[i] = array[i];
    
        2
  •  2
  •   Zeshan Qureshi    8 年前

    源和目标不兼容。
    字符*数组[4]; int*新_数组[2];

    我希望你把int搞错了?

        3
  •  0
  •   Myst    8 年前

    除了Jean-Fran§ois Fabre给出的精彩答案外,我还要指出,即使是已知大小也可以随着程序的发展而变化,因此,用已知终止符(即NULL或NaN)结束列表是有用的。

    我假设您刚刚开始学习C,但这是一个很好的习惯(将所有内容视为瞬态并最小化代码中的前置概念)。

    尽管人们指出 strdup 不是标准的C,它是广泛可用的。我会避免它只是为了好玩。我希望您注意到错误检查(过多?也许……但真正的代码应该充满这些东西)。

    考虑以下代码(但不要使用它,它可能会有点损坏):

    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char **string_array_dup(char *const *ary) {
      int count = 0;
      char **copy;
      if (!ary)
        return NULL;
      /* count string items - this is unsafe */
      while (ary[count++])
        ;
      if (!count)
          return NULL;
      /* allocate memory for array and set terminator. */
      copy = malloc(sizeof(*copy) * (count + 1));
      if (!copy)
        perror("ERROR"), exit(errno);
      copy[count - 1] = NULL;
      /* itterate over array, allocate and copy strings. */
      count = 0;
      while (ary[count]) {
        int register len = (int)strlen(ary[count]);
        copy[count] = malloc(len + 1); /* remember NUL byte */
        if (!ary[count])
          perror("ERROR"), exit(errno);
        memcpy(copy[count], ary[count], len + 1); /* copy NUL byte */
        count += 1;
      }
      return copy;
    }
    
    void string_array_print(char **ary) {
      int count = 0;
      while (ary[count]) {
        printf("%s ", ary[count++]);
      }
      printf("\n");
    }
    
    void string_array_free(char **ary) {
      int count = 0;
      /* free each string */
      while (ary[count]) {
        free(ary[count++]);
      }
      /* free container */
      free(ary);
    }
    
    int main(void) {
      char *array[] = {
          "String", "array", "is", "always", "terminated", "with", NULL,
      };
      char **copy = string_array_dup(array);
      if (!copy)
        perror("ERROR"), exit(errno);
      string_array_print(copy);
      string_array_free(copy);
      return 0;
    }
    

    顺便说一句,这段代码可以优化为只使用一个 malloc (或使用 realloc free -以更复杂的复制过程为代价(并改善数据的局部性和数据访问时间)。