我是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的“name”值设置为const char。我很难搞清楚这一点。这甚至是正确的方法吗?
非常感谢!
答案 0 :(得分:5)
好吧,你分配结构,但不是里面的字符串结构。在复制到它之前,您需要这样做。即使你这样做,当你试图设置字符串终止符时,你可能会覆盖未分配的内存。
而且,由于摄入过多的酒,我只是注意到你实际上只复制了一个字符,但它仍然是未定义的行为。
答案 1 :(得分:3)
让我们一步一步:
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*
操作的隐式长度字符串。如果做得好,它至少是安全的(通常更安全)和更有效率。
如果strncpy
是固定大小的数组,则可以使用t1->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
的{{1}}参数应始终为目标的大小,而不是源的大小,以避免在目标缓冲区的边界外写入。< / p>
答案 2 :(得分: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
}
答案 3 :(得分:1)
strncpy()总是错误
相反,你可以使用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;
}