将字符数组传递给结构体成员

4

我有以下结构:

struct hashItem {
    char userid[8];
    char name[30];
    struct hashItem *next;
};

在下面的函数中,我使用一个 char 指针(char 数组)参数,希望将其赋值给结构体。
void insertItem(struct hashItem *htable[], char *userid, char *name)
{
    int hcode = hashCode(userid);
    struct hashItem *current = htable[hcode];

    struct hashItem *newItem = (struct hashItem*) malloc(sizeof(struct hashItem));
    newItem->userid = userid;
    newItem->name = name;
    [...]
}

然而我收到了以下错误信息:

hashtable.c: In function ‘insertItem’:
hashtable.c:62: error: incompatible types in assignment
hashtable.c:63: error: incompatible types in assignment

第62行和63行是“newItem->...”行。

3个回答

7

你几乎肯定不想仅仅将char*赋值给char[] - 正如编译器所指出的,这些类型不兼容,语义也不是你想要的。我假设你希望结构体成员包含两个char*字符串的值 - 在这种情况下,你需要调用strncpy。

strncpy(target, source, max_chars);

假设我在代码的其他地方确定char数组小于给定的8/30字节长度,我该如何直接赋值而不是复制它? - Christian P.
在这种情况下,您可以在结构体中使用char,并将指针复制到另一个位置。char只是指向包含字符的某些内存的指针。char[]是为n个字符分配的固定长度存储空间。您无法以明智的方式在它们之间进行赋值。 - Adam Wright
@Christian:确保长度与分配或复制无关。在C语言中,您永远无法将数组分配给其他值,这是该语言所不允许的。您必须决定新的hashItem是否包含传递给insertItem的字符串的副本(在这种情况下,使用某种类型的副本以及某种类型的边界检查),或者是一个指向它的指针(在这种情况下,在struct中使用char*而不是char[])。 - Steve Jessop

0
你不能像你试图做的那样将指向字符串的指针分配给字符数组。相反,你需要使用Adam所示的strncpy复制字符串的内容:
strncpy (newItem->userid, userid, 8);

当您在结构体中声明一个字符数组时,您正在分配内存到结构体本身中以存储给定长度的字符串。

当您将指针传递到函数中时,您正在传递一个内存地址(一个整数),该地址指示可以找到以空字符结尾的字符串。

将指针分配给数组没有意义。数组已经为其分配了内存--它不能被“指向”另一个位置。

虽然您可以在结构体中使用指针,但是在分配它们时,必须非常小心,以确保告诉它们指向在您使用结构体期间将保持有效的内容。例如,此代码是错误的,因为传递给insertItem的字符串在fillStructure返回后不再存在:

struct hashItem
{
   char * userid;
};

void insertItem (struct hashItem * item, char * userid)
{
   item->userid = userid;
}

void fillStructure (struct hashItem * item)
{
   const char string[] = "testing";
   insertItem (item, string);
}

int main(void)
{
   struct hashItem item;
   fillStructure (&item);
   /* item->userid is now a dangling pointer! */
}

如果想了解更多,我建议阅读C FAQ中的“数组和指针”章节--从问题6.2开始阅读,并继续往下阅读。


在这里插入有关strncpy的常规参数:如果传入的用户ID恰好为8个字符长,则此代码将导致存储的字符串未被空终止。这可能不是您想要的结果。 - Steve Jessop

0

你应该更改你的结构体

struct hashItem {
  char userid[8];
  char *name;
  struct hashItem *next;
};

将一个字符指针分配给一个名称。在你定义的结构体中,char name[30] 只有30个字符。


当然,假设调用insertItem的程序保证名称字符串在hashItem对象的生命周期内始终有效。 - Steve Jessop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接