Structs inside Structs in sequence - c

I wanna do a program about blackjack game, but i am trying of a different way, but i don't know if is possible.
The code is compiled but when start the program, it closes:
blackjack.exe has stopped working
A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available.
#include <stdio.h>
#include <stdlib.h>
#define NUMBER_PLAYERS 6
#define NUMBER_SUITS 4
#define NUMBER_RANKS 13
#define NUMBER_CARDS (NUMBER_SUITS * NUMBER_RANKS)
typedef unsigned int uint;
typedef struct
{
uint suit;
uint rank;
} Card;
typedef struct card
{
Card card;
struct card *next;
} card;
typedef struct match
{
card *list;
struct match *next;
} Match;
typedef struct
{
char *name;
uint wins;
uint losses;
Match *match;
} Player;
void main(void)
{
Player player[NUMBER_PLAYERS];
uint i, j, count = 0;
char *op;
for(i = 0; i < NUMBER_PLAYERS; i++)
{
printf("Name: ");
scanf("%[^\n]s%*c", &player[i].name);
printf("\n\n");
player[i].losses = 0;
player[i].wins = 0;
player[i].match->next = NULL;
player[i].match->list->next = NULL;
}
getchar();
}

Player *player[NUMBER_PLAYERS]; // it's an array of pointers,
-> Any item in the array needs to point to a Player before you use it
typedef struct match
{
card *list; // it's a pointer
struct match *next;
} Match;
-> card *list is also needs to point to an initialized card
#include <stdio.h>
#include <stdlib.h>
#define NUMBER_PLAYERS 6
typedef unsigned int uint;
typedef struct
{
uint suit;
uint rank;
} Card;
typedef struct card
{
Card card;
struct card *next;
} card;
typedef struct match
{
card *list;
struct match *next;
} Match;
typedef struct
{
char *name;
uint wins;
uint losses;
Match *match;
} Player;
void main(void)
{
Player player[NUMBER_PLAYERS];
card cardList[NUMBER_PLAYERS];
uint i;
for(i = 0; i < NUMBER_PLAYERS; i++)
{
player[i] = NULL;
printf("Name: ");
scanf("%[^\n]s%*c", &player[i].name);
printf("\n\n");
player[i].name;
player[i].losses = 0;
player[i].wins = 0;
player[i].match->next = NULL;
player[i].match.list = &cardList[i];
player[i].match.list->next = NULL;
}
getchar();
}

Q: Why not just Player player[NUMBER_PLAYERS];? Why a pointer to an array, instead of just an array?
SUGGESTION: Change to scanf("s%", player[i]->name); I assume all you want is to input the name, correct?
SUGGESTION: Create one or more "init_xxx)" functions to initialize your structure (including substructures and/or link pointers) as needed.
Q: What is player[i]->name; supposed to do? Why not just delete that line?
Q: What do you mean by "when start the program, it close: This program has stop working..."? I notice you have a "getchar()" - does it skip right past getchar()" and terminate? Does the behavior change when you change the "scanf()"? Do you get an error message in any case?
Q: What compiler are you using? Are you on Windows, Linux or "something else"? Are you using an IDE (like Eclipse/CDT, or Visual Studio)?

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 read data structure from node list with custom types in c

Please help me to find a way read/add something to this data list by C language. I am confused in with typeDef statement.
typedef struct price
{
unsigned dollars;
unsigned cents;
} Price;
/**
* Stores data for a stock item.
**/
typedef struct stock
{
char id[ID_LEN + NULL_SPACE];
char name[NAME_LEN + NULL_SPACE];
char desc[DESC_LEN + NULL_SPACE];
Price price;
unsigned onHand;
} Stock;
/**
* The node that holds the data about an item stored in memory.
**/
typedef struct node
{
Stock *data;
struct node *next;
} Node;
/**
* The list of products - each link in the list is a Node.
**/
typedef struct list
{
Node *head;
unsigned size;
} List;
In order to correctly write in memory, you need to correctly allocate the latter.
I leave you here an example (I omitted all the checks, but these should be done!):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 5
#define ID_LEN 64
#define NAME_LEN 64
#define DESC_LEN 64
typedef struct price
{
unsigned dollars;
unsigned cents;
} Price;
/**
* Stores data for a stock item.
**/
typedef struct stock
{
char id[ID_LEN];
char name[NAME_LEN];
char desc[DESC_LEN];
Price price;
unsigned onHand;
} Stock;
/**
* The node that holds the data about an item stored in memory.
**/
typedef struct node
{
Stock *data;
struct node *next;
} Node;
/**
* The list of products - each link in the list is a Node.
**/
typedef struct list
{
Node *head;
unsigned size;
} List;
int main() {
List l;
int i;
l.size = N;
l.head = (Node*) malloc (l.size * sizeof(Node));
for (i = 0; i < l.size; i++) {
l.head[i].data = (Stock*) malloc (sizeof(Stock));
}
//you can now fill you data
//example
strcpy(l.head[0].data->id, "test\n");
printf("id of element 0: %s\n", l.head[0].data->id);
//example
strcpy(l.head[1].data->name, "Paul\n");
printf("name of element 1: %s\n", l.head[1].data->name);
//example
l.head[2].data->price.dollars = 99;
l.head[2].data->price.cents = 99;
printf("price of element 2: %d.%d $\n", l.head[2].data->price.dollars, l.head[2].data->price.cents);
return 0;
}
You can run it and check that everything is stored fine.
NOTE: I didn't connect the node pointer next!

Error in the use of linked-lists in C

The function doesnt work. The rest of the code is okay. It finds the maximum in the lists (its also the last element of the list) and then doesn't quit the iteration, instead of that, the program crashes. I got a hint, that suggests, that I have problems wit the us of "()". Maxhelye means the max_pos
typedef short int shorti;
typedef struct szelveny{
int szsorszam;
int lsorszam;
int het;
shorti talalat;
int tnyeremeny;
}szelveny; //szelveny-->ticket, szsorszam-->ticketnumer, //lsorszam-->lotterynumber,het-->week, tnyeremeny-->prize
typedef struct szelveny_element{
szelveny szelveny;
struct szelveny_element *next;
}szelveny_element,*szelveny_pointer;
typedef struct lottozo{
int lsorszam;
shorti het;
int sszelveny;
int nyeremeny;
} lottozo; //lottozo-->lottery
typedef struct lottozo_element{
lottozo lottozo;
struct lottozo_element *next;
} lottozo_element,*lottozo_pointer;
typedef struct het{
shorti het;
lottozo_pointer lhead;
szelveny_pointer szhead;
} het;
typedef struct het_element{
het het;
struct het_element *next;
}het_element,*het_pointer;
szelveny_pointer szelvenyek=0;
lottozo_pointer lottozok=0;
het_pointer hetek=0;
int maxnyeremenyhelye2(int ahet) //maxprizeposition, ahet-->week got as parameter
{
int max=0,maxhelye=-1;
het_pointer hp;
for(hp=hetek;hp!=0;hp=hp->next)
if(hp->het.het==ahet)
{
lottozo_pointer lp;
for(lp=hp->het.lhead;lp!=0;lp=lp->next)
{
if(lp->lottozo.nyeremeny>=max)
{
max=lp->lottozo.nyeremeny;
maxhelye=lp->lottozo.lsorszam;
}
}
return maxhelye;
}
}
Your function int maxnyeremenyhelye2(int ahet) does not always return a value - didn't your compiler warn you about this? The line
return maxhelye;
should be moved down below the following brace.

error: invalid type argument of '->' (have 'struct node')

Why cant i access the pointer "Cells" like an array ? i have allocated the appropriate memory why wont it act like an array here? it works like an array for a pointer of basic data types.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 10
struct node
{
int e;
struct node *next;
};
typedef struct node *List;
typedef struct node *Position;
struct Hashtable
{
int Tablesize;
List Cells;
};
typedef struct Hashtable *HashT;
HashT Initialize(int SIZE,HashT H)
{
int i;
H=(HashT)malloc(sizeof(struct Hashtable));
if(H!=NULL)
{
H->Tablesize=SIZE;
printf("\n\t%d",H->Tablesize);
H->Cells=(List)malloc(sizeof(struct node)* H->Tablesize);
should it not act like an array from here on?
if(H->Cells!=NULL)
{
for(i=0;i<H->Tablesize;i++)
the following lines are the ones that throw the error
{ H->Cells[i]->next=NULL;
H->Cells[i]->e=i;
printf("\n %d",H->Cells[i]->e);
}
}
}
else printf("\nError!Out of Space");
}
int main()
{
HashT H;
H=Initialize(10,H);
return 0;
}
The error I get is as in the title-error: invalid type argument of '->' (have 'struct node').
A correct version of your code is given below. It is always advisable not to use pointers while using typedef.
The only problem with your code apart from that was your access method.
H->cells[i]->next will throw an error.
Also H->cells->[i]e was invalid syntax.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 10
struct node
{
int e;
struct node *next;
};
typedef struct node List;
typedef struct node Position;
struct Hashtable
{
int Tablesize;
List *Cells;
};
typedef struct Hashtable HashT;
HashT Initialize(int SIZE,HashT *H)
{
int i;
H=(HashT*)malloc(sizeof(struct Hashtable));
if(H!=NULL)
{
H->Tablesize=SIZE;
printf("\n\t%d",H->Tablesize);
H->Cells=(List*)malloc(sizeof(List)*H->Tablesize);
//should it not act like an array from here on?
if(H->Cells!=NULL)
{
for(i=0;i<H->Tablesize;i++)
//the following lines are the ones that throw the error
{
H->Cells[i].next=NULL;
H->Cells[i].e=i;
printf("\n %d",H->Cells[i].e);
}
}
}
else printf("\nError!Out of Space");
return *H;
}
int main()
{
HashT H;
H=Initialize(10,&H); //return is not required as already we are passing by address
return 0;
}
The
H->Cells[i]->next
should be
H->Cells[i].next
(Similarly for e.)
This is a version of your program without the typedefs. Which one is more readable?
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *next;
int e;
};
struct Hashtable {
unsigned Tablesize;
struct node *Cells;
};
struct Hashtable *Initialize(unsigned size)
{
unsigned iii;
struct Hashtable *hp;
hp = malloc (sizeof *hp);
if(!hp) {
fprintf(stderr, "Error!Out of Space\n");
return NULL;
}
hp->Cells = malloc(size * sizeof *hp->Cells );
if(!hp->Cells) {
hp->Tablesize = 0;
return hp;
}
hp->Tablesize = size;
fprintf(stderr, "\t%u\n", hp->Tablesize);
for(iii=0; iii < hp->Tablesize; iii++) {
hp->Cells[iii].next = NULL;
hp->Cells[iii].e = iii;
fprintf( stderr, " %u\n", hp->Cells[iii].e);
}
return hp;
}
int main()
{
struct Hashtable *hashtab;
hashtab = Initialize(10);
return 0;
}
The changes:
removed the typedefs; since they are confusing
removed the casts from malloc() not needed and potentially dangerous.
changed the sizes to unsigned. A size can never be negative
diagnostic output should go to stderr.
a few of levels of indentation can be avoided by doing the error-case first, and returning early from the function on error.

pointers to structs inside union: how to initialize and retrieve struc values

I have the following simple code. I am trying to understand how I can use structs inside unions and how I can retrieve contents of struct variables in connection with unions.
Here is a small sample code I have written. I want to retrieve the "Maker" struct variables from this code. How should I correctly do it? My code here results in segmentation fault.
Here is the updated code :
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char *name;
int *wheels;
}CarVendor;
typedef struct{
char *name;
int *wheels;
int seats;
}BusVendor;
typedef union{
CarVendor *carvendor;
BusVendor *busvendor;
}Maker;
typedef struct{
Maker *carType;
}Car;
typedef struct{
Maker *busType;
}Bus;
typedef union{
Car *car;
Bus *bus;
}Vehicle;
void fillDetails(Vehicle *vehicle, int type){
if(type == 0){
vehicle->car->carType->carvendor->name = "car";
int wheel = 4;
vehicle->car->carType->carvendor->wheels = &wheel;
}
if(type ==1){
vehicle->bus->busType->busvendor->name = "bus";
int wheel = 6;
vehicle->bus->busType->busvendor->wheels = &wheel;
vehicle->bus->busType->busvendor->seats = 60;
}
}
int main(int argc, char *argv[])
{
Vehicle myvehicle;
fillDetails(&myvehicle, 0); //get car details filled & retrieve the details as "Maker" struct
Maker *maker;
maker = (Maker *) malloc(sizeof(Maker));
maker = myvehicle.car->carType;
printf("Name of car =%s", maker->carvendor->name);
return 0;
}
Are you sure you want everything to be on the heap?
If you really want to, you need to malloc memory for ALL the structures that you've got pointers to (or at least the ones you want to access, e.g. from fillDetails), and clean up afterwards. Your union, e.g. Maker, essentially just says that this pointer can be one of two types, either a CarVendor, or a BusVendor.
If you want to do this kind of stuff it sometimes makes sense to have a "type" distinguisher in the structure, such that the code looking at it later knows which type the pointer has. Here's an example:
typedef struct a_t_ { /*...*/ } a_t;
typedef struct b_t_ { /*...*/ } b_t;
typedef enum mytype_t_ {a, b} mytype_t;
typedef struct foo_t_ {
mytype_t type_of_the_below;
union {
a_t *a;
a_t *b;
};
} foo_t;
Again, notice that you need to malloc the memory for the Maker before you access it from fillDetails, not after.
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char *name;
int *wheels;
}CarVendor;
typedef struct{
char *name;
int *wheels;
int seats;
}BusVendor;
typedef union{
CarVendor *carvendor;
BusVendor *busvendor;
}Maker;
typedef struct{
Maker *carType;
}Car;
typedef struct{
Maker *busType;
}Bus;
typedef union{
Car *car;
Bus *bus;
}Vehicle;
void fillDetails(Vehicle *vehicle, int type){
if(type == 0){
vehicle->car->carType->carvendor->name = "car";
int wheel = 4;
vehicle->car->carType->carvendor->wheels = &wheel;
}
if(type ==1){
vehicle->bus->busType->busvendor->name = "bus";
int wheel = 6;
vehicle->bus->busType->busvendor->wheels = &wheel;
vehicle->bus->busType->busvendor->seats = 60;
}
}
int main(int argc, char *argv[])
{
Vehicle myvehicle;
myvehicle.car = (Car*) malloc(sizeof(Car));
myvehicle.car->carType = (Maker*)malloc(sizeof(Maker));
myvehicle.car->carType->carvendor = (CarVendor*) malloc(sizeof(CarVendor));
fillDetails(&myvehicle, 0); //get car details filled & retrieve the details as "Maker" struct
Maker *maker = NULL;
maker = myvehicle.car->carType;
printf("Name of car =%s\n", maker->carvendor->name);
free(myvehicle.car->carType->carvendor);
free(myvehicle.car->carType);
free(myvehicle.car);
return 0;
}
Here's how you can more safely do it on the stack...
#include <stdio.h>
#include <stdlib.h>
typedef struct{
char *name;
int wheels;
}CarVendor;
typedef struct{
char *name;
int wheels;
int seats;
}BusVendor;
typedef union{
CarVendor carvendor;
BusVendor busvendor;
}Maker;
typedef struct{
Maker carType;
}Car;
typedef struct{
Maker busType;
}Bus;
typedef union{
Car car;
Bus bus;
}Vehicle;
void fillDetails(Vehicle *vehicle, int type){
if(type == 0){
vehicle->car.carType.carvendor.name = "car";
int wheel = 4;
vehicle->car.carType.carvendor.wheels = wheel;
}
if(type ==1){
vehicle->bus.busType.busvendor.name = "bus";
int wheel = 6;
vehicle->bus.busType.busvendor.wheels = wheel;
vehicle->bus.busType.busvendor.seats = 60;
}
}
int main(int argc, char *argv[])
{
Vehicle myvehicle;
fillDetails(&myvehicle, 0); //get car details filled & retrieve the details as "Maker" struct
Maker *maker;
maker = &myvehicle.car.carType;
printf("Name of car =%s\n", maker->carvendor.name);
return 0;
}

Resources