C strcpy 字符串指针数组

C strcpy array of string pointers

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

char *array[4];

由带字符串的不同函数填充,即 ["one"、"two"、"three"、"four"].

我的目标是将这个数组复制到一个新数组中,不包括最后两个元素,因此 new_array 将包含 ["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 *’

extern char *strncpy (char *__restrict __dest,

您的代码存在一些问题

首先它声明了一个整数指针数组(因此警告)然后这些指针没有被初始化。 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];

源和目标不兼容。
字符*数组[4]; 整数 *new_array[2];

希望你打错了?

除了让-弗朗索瓦·法布尔 (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 - 代价是更复杂的副本过程(并改进数据的局部性和数据访问时间)。