c-使用strncpy()复制constchar*



我对C很陌生,我在使用strncpy函数时遇到了麻烦

以下是我正在使用的示例:

int main()
{
const char *s = "how";
struct test {
    char *name;
};
struct test *t1 = malloc(sizeof(struct test));
strncpy(t1->name, s, sizeof(*s));
t1->name[NAMESIZE] = '';
printf("%sn", t1->name);
}

我有一个const char*,我需要将test的"name"值设置为const char。我很难弄清楚这一点。这是正确的方法吗?

非常感谢!

好吧,您分配结构,但不分配结构内部的字符串。在复制到它之前,你需要这样做。即使这样做,当你试图设置字符串终止符时,你也可能会覆盖未分配的内存。

而且,由于大量饮酒,我刚刚注意到你实际上只复制了一个字符,但它仍然是未定义的行为。

让我们一步一个脚印:

struct test *t1 = malloc(sizeof(struct test));

这为CCD_ 1分配空间;足够的空间用于指针name,但没有任何内存用于指针指向。至少,您需要执行以下操作:

t1->name = malloc(strlen(s) + 1);

完成后,您可以继续复制字符串。但是,您已经计算了一次字符串的长度来分配内存;通过调用CCD_ 3来隐式地再次执行它是没有意义的。相反,请执行以下操作:

const size_t len = strlen(s) + 1;  // +1 accounts for terminating NUL
t1->name = malloc(len);
memcpy(t1->name, s, len);

一般来说,尽量使用这个基本模式;当字符串进入代码时,计算它们的长度一次,但随后使用显式大小的内存缓冲区和mem*操作,而不是使用str*操作的隐式长度字符串。如果操作得当,它至少同样安全(而且通常更安全),效率更高。

如果t1->name是固定大小的数组,则可以使用strncpy(尽管许多人更喜欢使用strlcpy)。看起来如下:

struct test { char name[MAXSIZE]; };
struct test *t1 = malloc(sizeof *t1);
strncpy(t1->name, s, MAXSIZE - 1);
t1->name[MAXSIZE-1] = 0; // force NUL-termination

请注意,struct test0的size参数应始终是目标的大小,而不是源,以避免在目标缓冲区的边界之外写入。

在不尝试任何完整性或教育指导的情况下,以下是您的代码版本。你可以玩"发现差异"游戏,并在这个网站上分别搜索每一个解释。

int main()
{ 
    const char s[] = "how";                 // s is an array, const char[4]
    struct test{ char name[NAMESIZE]; };    // test::name is an array
    struct test * t1 = malloc(sizeof *t1);  // DRY
    strncpy(t1->name, s, NAMESIZE);         // size of the destination
    t1->name[NAMESIZE - 1] = '';          // because strncpy is evil
    printf("%sn", t1->name);
    free(t1);                               // clean up
}

strncpy()总是错误

  • 如果结果太长,目标字符串将不会以nul结尾
  • 如果目标太长(第三个参数),则尾部将完全填充NUL。如果您有大的缓冲区和短字符串,这将浪费大量的周期

相反,您可以使用memcpy()或strcpy,(在您的情况下,甚至使用strdup())

int main()
{
const char *s = "how";
struct test {
    char *name;
    };
struct test *t1
size_t len;
t1 = malloc(sizeof *t1);
#if USE_STRDUP
  t1->name = strdup(s);
#else
  len = strlen(s);
  t1->name = malloc (1+len);
  memcpy(t1->name, s, len);
  t1->name[len] = '';
#endif    
printf("%sn", t1->name);
return 0;
}

相关内容

  • 没有找到相关文章

最新更新