How to assign values to a list in C - c

I have this list and I'm writing a function to ask the user to add the info:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXTAB 40
#define MAXSTR 25
typedef enum {Prob, Impr, Terr, Jail} Type;
typedef struct {
int pos;
char name[MAXSTR+1];
char owner[MAXSTR+1];
int price;
Type info;
} Casella;
struct lista {
Casella Tab;
struct lista *node;
};
typedef struct lista Lista;
void printElement (Lista *);
void printTab (Lista *);
Lista * initializeTab (Lista *, int);
Lista * addInfo (Lista*);
int main()
{
Lista *list = NULL;
int i;
for (i=0; i<MAXTAB; i++){
list = initializeTab(list, i);
}
printTab(list);
return 0;
}
void printElement (Lista *l){
printf("Position: %d\n", l->Tab.pos);
}
void printTab (Lista *l){
while(l!=NULL){
printElement(l);
l=l->node;
}
}
Lista * initializeTab (Lista *l, int x){
Lista *newTab = NULL;
newTab = (Lista*)malloc(sizeof(Lista));
newTab->Tab.pos = x;
newTab->node = l;
return newTab;
}
Lista * addInfo (Lista *l){
Lista *list = NULL;
list->Tab.name = (char*)malloc(MAXSTR * sizeof(char));
return list;
}`
In the function "addInfo", I try to allocate memory for the Tab name, but it tells me I can't assign type array char to that. My question is, how do I allocate memory for various list elements? Like I want to allocate memory for the list.name, then list.owner, list.pos etc... and then assign values to them.

In your structure definition
struct {
int pos;
char name[MAXSTR+1]; //array
char owner[MAXSTR+1]; //array
int price;
Type info;
} Casella;
name and owner are arrays, and they already have [MAXSTR+1] elements each. You don't need to allocate memory using malloc(). Just do strcpy().
Also, pos being an integer, simply assign the value using =. That should suffice.
Where you need to allocated memory is to list, which is a pointer. Something like
Lista *list = malloc(sizeof*list); //and a NULL check later
is required in first place.

Arrays in c are non-writeable lvalues, to achieve what you want you need to use a pointer instead, change the structure definition to this
typedef struct {
int pos;
char *name;
char *owner;
int price;
Type info;
} Casella;
Also, you malloc() and the pointer points to valid uninitialized memory so if you try to read from it undefined behavior will happen, try to change the addInfo() function to something like this
Lista *
addInfo (Lista *lista, const char *const name)
{
lista->Tab.name = strdup(name);
return lista;
}
Another very important mistake is that you set list to NULL inside addInfo() and then immediately dereference it, that is surely undefined behavior and the most likely outcome is that your program will crash.

Related

Can a pointer point to a struct of item of list of order

typedef struct item
{
char itemName[32];
float price;
int quantity;
}ITEM;
typedef struct list
{
void* item[5];
int (*compare)(void*, void*);
int length;
}LIST;
typedef struct order
{
int orderId;
float orderTotal;
LIST* orderItems;
int length;
} ORDER;
int compareItemPrice(void* p1, void* p2){
ITEM* p = (ITEM*)p1;
ITEM* q = (ITEM*)p2;
if(p->price>q->price)
{
return 1;
} else if(p->price<q->price)
{
return -1;
} else {
return 0;
}
}
Code above is my structures and function wrote in C. When I implement code below, it showed me errors. The errors was all about ITEM* p which was incomplete definition of struct list.
ITEM* getExpensiveItem(ORDER* o){ // Maximum item price
ITEM* p = o->orderItems->item;
ITEM* expensiveItem = p;
for(int i=1; i<o->orderItems->length-1; i++)
{
if(compareItemPrice(p, (p+i)) < 0)
{
expensiveItem = p+i;
}
}
return expensiveItem;
}
Code like
struct a
{
int i;
} A;
will give a variable A that you can use like
A.i = 42;
However, it seems that you really are trying to create a new type. So try:
typedef struct a // Notice the "typedef" in start of line
{
int i;
} A;
That will give a a type A that can be used like:
A var;
A* pVar;
var.i = 42;
pVar = &var;
....
Also notice that your struct order uses the type LIST. So LIST must be declared before struct order. Further, the type CUSTOMER must also be declared which it currently isn't.
So your code should probably be like:
#define N 42 // Made this up as it isn't in your code
typedef struct customer // Made this up as it isn't in your code
{
int x;
} CUSTOMER;
typedef struct list
{
void* item[N];
int (*compare)(void*, void*);
int length;
}LIST;
typedef struct order
{
int orderId;
float orderTotal;
LIST* orderItems;
CUSTOMER* customer;
int length;
} ORDER;
typedef struct item
{
char itemName[32];
float price;
int quantity;
}ITEM;
Also notice that this line has a problem:
ITEM* p = o->orderItems->item;
The type of o->orderItems->item is array of void pointer due to void* item[N]; in struct list. In other words: You are trying to assign an array of pointer to a single pointer. I'm not really sure what you want to do but maybe like:
ITEM* p = o->orderItems->item[0];

how to make structs point to different strings?

I have a struct and in that a struct i have a character pointer but and i am creating different instances of this struct but when i am changing the pointer in one struct the other is also changing.
#include <stdio.h>
#include <stdlib.h>
typedef struct human{
int age;
char name[100];
} Human;
int main(){
FILE *s = fopen("h.txt","r");
if(s==NULL){
printf("file not available");
}
for(int i=0 ;i<5;i++){
Human h;
fscanf(s,"%d",&h.age);
fscanf(s,"%s",h.name);
insertintolinkedlist(h);
// this method is going to insert the human into the linked list
}
return 0;
}
what is happening that all humans in the linked list have different ages but same name!
You need to allocate memory to hold the name.
char* name is just a pointer - it has no memory for saving the name.
You change it to
char name[100];
Remember to check that the names you put into Human.name isn't longer than 100 characters.
To use a linked list you can do something like:
typedef struct human{
int age;
char name[100];
struct human* next;
} Human;
int main()
{
Human* head = NULL;
Human* tail = NULL;
for(.....)
{
Human* h = malloc(sizeof(Human));
if (head == NULL) head = h;
if (tail != NULL)
{
tail->next = h;
}
tail = h;
h->next = NULL;
h->age = ....;
strncpy(h->age, "..name..", 100);
}
// ..... other code
// Remember to free all allocated memory
}

Strings dynamic allocation in C

I'm working with C. Can you tell me if this is the right way to allocate memory for a struct which contains a string?
struct _TipoLista {
char info[10];
struct _TipoLista *next;
};
typedef struct _TipoLista *TipoLista;
...
TipoLista el;
el = malloc(sizeof(TipoLista));
If a try to create a list in this way, I always get errors when I try to insert the 2nd element while. However, if I change "info" from char[10] to an int my code always works.
el = malloc(sizeof(*el));
or
el = malloc(sizeof(struct _TipoLista));
or initializing while declaring the struct
struct _TipoLista {
char info[10];
struct _TipoLista *next;
}obj1;
In the first two cases it's dynamic memory allocation 3rd is static memory allocation
el = malloc(sizeof(*el));
TipoLista has size of a pointer so that's not what you really want.
You should try the following
el = malloc(sizeof(struct _TipoLista));
Or define a typedef for this structure.
You are trying to do a typedef i.e., an alias for the strucuture. Typedef in turn means that "from this point onwards *struct _TipoLista* will be called as *TipoLista "
If you want to have a linked list of type "struct _TipoLista", then this could help.
struct _TipoLista {
char info[10];
struct _TipoLista *next;
};
typedef struct _TipoLista TipoLista;
int main()
{
TipoLista *Tptr = malloc(sizeof(TipoLista) );
/** Rest is history */
}
Hope this can be useful:
typedef struct {
char info[10];
struct _TipoLista *next;
} TipoLista;
TipoLista* construct_lista()
{
TipoLista* ret = malloc(sizeof(TipoLista));
ret->next = NULL;
return ret;
}
void destruct_lista(TipoLista* lista)
{
TipoLista* next;
while (lista != NULL)
{
next = lista->next;
free(lista);
lista=next;
}
}
void insert_into_list(TipoLista* lista, char* element)
{
while (lista->next != NULL)
lista = lista->next;
lista->next = construct_lista();
strcpy(lista->next->info, element);
}

C: incompatible types in assignment

typedef char Last_t[MAXL];
typedef char Rest_t[MAXR];
typedef struct NodeTag {
Last_t Last;
Rest_t Rest;
struct NodeTag *Link;
} Node;
typedef struct {
Node *Index[26];
Node *L;
} ContactList;
// parameter to take in a char argument to set it to contact.Last
void INS( Node *cn )
Node contactName;
contactName.Last= cn;
// temp->data=num;
//contactName.Rest=restName;
}
//cant figure out how to pass a char argument
int main(void)
{
INS("David");
}
void INS should be passing an argument of type char *, not Node, if you want the code in your main to work.
To assign it to the member Last, you would have to use strcpy or something similar. This is because you can't assign a pointer to an array. More specifically, you can't assign a char * to char[MAXL].
You could try this:
void INS( char * cn ) {
Node contactName;
strncpy (contactName.Last, cn, MAXL);
}
int main(void){
INS("David");
return 0;
}
But, this doesn't handle errors very well. Here's a way of doing it that's more error-safe:
void INS (char * cn){
Node contactName = {
.Last[0] = 0,
.Rest[0] = 0,
.Link = 0
};
if (cn){
strncpy (contactName.Last, cn, MAXL - 1);
contactName.Last[MAXL - 1] = 0;
}
}
int main (void){
INS ("David");
return 0;
}

Memory Allocation for Function Pointer

I have a struct called warehouse and a generic linked list and each item points to a warehouse struct.
typedef struct linked{
char type;
void * item;
struct linked * next;
struct linked * prev;
}LinkedList;
typedef struct warehouse{
char * name;
float volume;
float (* getPrice) (void * S);
float (* getTotalDollarAmount)(void * S);
}house_t;
When I tried to get the getPrice function pointer point to a function float price (void *S)
void menu (LinkedList *house){
char *c;
float num;
c = (char*)malloc(sizeof(char)*10);
LinkedList *i;
i = (LinkedList*)malloc(sizeof(LinkedList);
house_t *sk;
sk = (house_t *) malloc(sizeof(house_t));
//i->item = (house_t *) malloc(sizeof(house_t));
scanf("%c", c);
((house_t*)i->item)->getPrice = price;
sk=findhouse(house, c);
num = ((house_t*)i->item)->getPrice(sk);
printf("%f",num);
}
I got bad access error. Since every time I got a bad access error it was because I didn't allocate memory for something. But do I need to allocate memory for function pointer? If so, how?
Here's some more code
float price (void *S)
{
return ((house_t*)S)->volume;
}
LinkedList *i;
i = NewLinkedList();
/* ... snip ... */
LinkedList *NewLinkedList()
{
return NULL;
}
According to your definition of NewLinkedList(), the variable i is now NULL. You try and dereference it with i->item = ... but you can't do this if i is NULL. I think what you really want to do is allocate space for your linked list in your NewLinkedList function:
LinkedList * NewLinkedList()
{
LinkedList *result = malloc(sizeof(LinkedList));
result->type = '\0'; // set to suitable initial value
result->item = NULL;
result->next = NULL;
result->prev = NULL;
return result;
}

Resources