Передача массива char в член структуры - PullRequest
4 голосов
/ 21 сентября 2009

У меня есть следующая структура:

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

В приведенной ниже функции я принимаю аргумент указателя на символ (массив символов), который я хочу присвоить структуре.

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 голосов
/ 21 сентября 2009

Вы почти наверняка не хотите просто назначать char * для char [] - как указывает компилятор, типы несовместимы, а семантика - не то, что вы думаете. Я предполагаю, что вы хотите, чтобы члены структуры содержали значения двух строк char * - в этом случае вы хотите вызвать strncpy.

strncpy(target, source, max_chars);
0 голосов
/ 21 сентября 2009

Вы должны изменить свою структуру в

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

для присвоения указателю символа имени. В структуре вы определили имя персонажа [30] - это всего лишь 30 символов.

0 голосов
/ 21 сентября 2009

Вы не можете назначить указатель на строку на массив символов, как вы пытаетесь. Вместо этого вам нужно скопировать содержимое строки с помощью 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 и продолжайте читать оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...