views:

152

answers:

4

I'm trying to create a structure storing strings and I'm getting an error incompatible types when I try and insert as string into the array. This my first time working with a program in C. Could somebody help spot my problem.

This is my implementation of list.c

struct list *init_list(int num) {
    struct list *p;
    p = malloc(LISTSZ(num));
    if(p == NULL)
        return(NULL);
    p->maxsz = num;
    p->sz = 0;
    return(p);
}

void debug_list(struct list *p) {
    int i;
    fprintf(stderr, "\nDynamic List\n\n");
    fprintf(stderr, "   sz  = %d\n", p->sz);
    fprintf(stderr, "   maxsz   = %d\n", p->maxsz);
    for(i = 0; i < p->maxsz; i++)
        fprintf(stderr,"    %s\n", (p->item[i]));
}

void prt_list(struct list *p) {
    int i;
    for(i = 0; i < p->sz; i++)
        printf("%s\n", (p->item[i]));
}

int ins_list(char *data, struct list **p) {
    struct list *q;
    if((*p)->sz == (*p)->maxsz) {
        q = realloc(*p, LISTSZ((*p)->maxsz + INCRSZ)); // Problem?
        if(q == NULL)
            return(-1);
        q->maxsz += INCRSZ;
        *p = q;
    }
    (*p)->item[(*p)->sz] = data; // incompatible types in assignment
    (*p)->sz ++;
    return(0);
}

This is my implementation of list.h

struct list {
    int sz;
    int maxsz;
    char item[][1024]; // Problem?
};

#define INITSZ 5
#define INCRSZ 5
#define LISTSZ(n) ((size_t)(sizeof(struct list) + ((n)-1)*sizeof(char[1024]))) // Problem?

struct list *init_list(int num);
int ins_list(char *data, struct list **p);
void prt_list(struct list *p);
void debug_list(struct list *p);
+4  A: 

You have an array of char, yet you're trying to put a char * into it.

I would guess that strncpy will do what you want. Alternatively, declare item as an array of char *.

Anon.
+3  A: 
struct list {
   int sz;
   int maxsz;
   char *item[1024]; 
};
IVlad
No - the OP's code was right - `item` is a C99 flexible array member.
caf
Using strncpy is one way of fixing the OP's code, but this will also fix it. I never said the declaration was wrong or anything, I just posted something that fixes his error. In my opinion this is preferable because it avoids an ugly strncpy call.
IVlad
The problem is that this changes the semantics of the code - the OP's code is clearly intended to have the list to store an independent copy of the data, not a pointer to it. Also, `strncpy` is almost certainly *not* the right function to use here.
caf
+2  A: 

Hi,

There more differences between C and C++ than it's commonly admit.

For your error the reason is simple you are trying to assign a pointer (char*) at sz wich is an int. This kind of assignment generate the incompatible type warning.

Second thing you can't do (a least as far as i know) a partially dynamic array as you do it. In your case you should use at least a malloc and the type of item should be char**. However there is a trick to use only one malloc to create a 2D array.

For the realloc nothing hit me ... What is the compilation error ?

However your code doesn't looks like C code :/

You might need to rebuild it form scratch, because you are here making confusion between lists and 2D arrays ...

I can write some examples of codes if you want but you should probably find a C basics tutorial on google.

Good luke :)

Niklaos
Where is he trying to assign a char * to the sz field? I think you meant to item, which isn't a char * array.
IVlad
A: 

At this line:

(*p)->item[(*p)->sz] = data; // incompatible types in assignment

(*p)->item[(*p)->sz] is an array of 1024 char - you can't assign to arrays with = (arrays are "non-modifiable lvalues").

You just need to do a copy. For a length-safe string copy, I prefer to use strncat():

(*p)->item[(*p)->sz][0] = '\0'; /* Truncate existing string to empty */
strncat((*p)->item[(*p)->sz], data, (sizeof (*p)->item[(*p)->sz]) - 1);
caf
Thank you. I think this is the problem that I needed to address for my code.
Cameron Lopez