繁体   English   中英

使用strncpy()复制const char *

[英]Using strncpy() to copy const char *

我是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] = '\0';

printf("%s\n", t1->name);

}

我有一个const char *,我需要将测试的“名称”值设置为const char。 我现在很难解决这个问题。 这甚至是正确的方法吗?

非常感谢你!

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

而且,由于葡萄酒摄入量较高,我刚刚注意到您实际上只复制了一个字符,但这仍然是不确定的行为

让我们一次迈出这一步:

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

这为struct test分配了空间; 足够的空间指针name ,而不是为指针指向的内存。 至少,您需要执行以下操作:

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

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

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

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

无需任何完整性或教育指导的尝试,这是您的代码应能运行的版本。 您可以在此站点上播放“发现差异”并分别搜索每个解释。

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] = '\0';          // because strncpy is evil

    printf("%s\n", 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] = '\0';

#endif    

printf("%s\n", t1->name);

return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM