2

我对 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 *,我需要将 test 的“名称”值设置为 const char。我很难弄清楚这一点。这甚至是正确的方法吗?

非常感谢!

4

4 回答 4

5

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

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

于 2013-02-09T19:40:35.357 回答
3

让我们一步一步来:

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

这为 a 分配空间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*。如果操作得当,它至少同样安全(而且通常更安全)和更有效。

您可以改用strncpyift1->name是一个固定大小的数组(尽管许多人更喜欢使用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

请注意,size参数 tostrncpy应该始终是目标的大小,而不是源的大小,以避免写入目标缓冲区的范围之外。

于 2013-02-09T19:54:11.013 回答
2

在不尝试完整性或教育方向的情况下,这里有一个应该可以工作的代码版本。您可以在本网站上播放“找出不同之处”并分别搜索每一个的解释。

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
}
于 2013-02-09T19:50:25.207 回答
1

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;
}
于 2013-02-09T20:00:42.123 回答