How to nest structures? - c

typedef struct{
char name_cake[10];
char code_cake[10];
int stock_cake;
char about_cake[10];
char cake_taste[10];
}order;
typedef struct{
char name_cake[10];
char code_cake[10];
int stock_cake;
char about_cake[10];
char cake_taste[10];
}cake;
how to the contents of typedef struct become one? and I can invoke the command with
information.order.name_cake
information.cake.name_cake
for simply and not waste of words, thank

I would recommend to use the same struct for cake and order, there is no polymorphism in c

To access them in the way you like:
#include <stdio.h>
typedef struct{
char name_cake[10];
char code_cake[10];
int stock_cake;
char about_cake[10];
char cake_taste[10];
}order;
typedef struct{
char name_cake[10];
char code_cake[10];
int stock_cake;
char about_cake[10];
char cake_taste[10];
}cake;
typedef struct {
union {
order the_order;
cake the_cake;
}; // anonymous union
}information;
int main() {
order an_order = {"cakename", "code", 0, "about", "taste"};
information info = *((information*)&an_order);
printf("From order: %s\n", info.the_order.name_cake);
printf("From cake: %s\n", info.the_cake.name_cake);
return 0;
}
$ gcc -Wall ordercake.c
$ ./a.out
From order: cakename
From cake: cakename
$
In general you want to do object-oriented programming in C. Therefore, take a look at: How can I simulate OO-style polymorphism in C? (There is even a free book as pdf linked on how to do it.)
And now an example for a struct in a struct:
#include <stdio.h>
typedef struct{
char name_cake[10];
char code_cake[10];
}cake;
typedef struct{
cake the_cake; // the common part
char cake_extension[10]; // the new part, order is important
}extended_cake;
int main() {
extended_cake an_extended_cake = {{"cakename", "code"}, "extension"};
// now treat it as a cake
cake *a_normal_cake = (cake *)&an_extended_cake;
printf("From cake: %s\n", a_normal_cake->name_cake);
return 0;
}
$ gcc -Wall ordercake.c
$ ./a.out
From cake: cakename
$

Not sure what you're going to do, but you can simply nest structures like this:
struct foo {
order order;
cake cake;
}
If you want the contents of order and cake occupy the same memory space, you should use an anonymous union, as written above.

#include<stdio.h>
#include<string.h>
struct sports
{
char name[40];
int age;
/*nested structure*/
struct medicaltests
{
char isFit[1];
} med;/*nested object*/
};
int
main ()
{
struct sports sportobj;/*Declare object*/
strcpy (sportobj.name, "venkateshwar krishnan");
sportobj.age = 40;
strcpy (sportobj.med.isFit, "Y");
printf ("name of sportsman%s\n", sportobj.name);
printf ("IsFit %s", sportobj.med.isFit);
return 0;
}

Related

Automatic generation of struct printing function in C

I have many programs where structs are defined. And each time, I have to create a function to print the members. For example,
typedef struct {
char name[128];
char address[1024];
int zip;
} myStruct;
void printMyStruct(myStruct myPeople) {
printf("%s\n",myPeople.name);
printf("%s\n",myPeople.address);
printf("%d\n",myPeople.zip);
}
int main()
{
myStruct myPeople={"myName" , "10 myStreet", 11111};
printMyStruct(myPeople);
}
I know that reflection is not supported in C. And so, I write these printing functions for each struct I defined.
But, I wonder if it exists any tricks to generate automatically these printing functions. I would understand that I have to modify a little bit these functions. But, if a part of the job is done automatically, it would be great.
(This example is simple, sometimes struct are nested or I have array of structs or some fields are pointers, ...)
You can of-course print structs, but expect a lot of non-readable output:
#include <stdio.h>
#include <ctype.h>
struct example {
int x;
int y;
char c;
};
#define NOT_PRINTABLE "Not Printable"
void print_structure(const char *structure, size_t size) {
for (size_t i = 0; i < size; i++) {
printf("%ld)\t%.2X: %.*s\n", i, structure[i],
(isprint(structure[i]) ? 1 : sizeof(NOT_PRINTABLE) - 1),
(isprint(structure[i]) ? &structure[i] : NOT_PRINTABLE));
}
}
int main(int argc, char **argv) {
struct example a;
a.x = 5;
a.y = 6;
a.c = 'A';
print_structure((char *)&a, sizeof(struct example));
return 0;
}
But the issue is that, it will print the structs as it is represented in memory. So 4 byte (32 bit) integer 1 will be represented with 4 bytes, not the char '1'.
And due to the way pointers work, you cannot make out if a member is a pointer or a non-pointer.
Another issue is that structures have padding to help with alignment, and better/efficent use of memory. So you would see a lot of 0x00 in the middle.
Remember that C is a compiled language.
let's consider to use https://copilot.github.com/. it's great.
this is what i have with copilot
typedef struct {
char name[128];
char address[1024];
int zip;
} myStruct;
//print struct myStruct >> auto generate by codepilot after you type a comment `print struct myStruct`
void printStruct(myStruct *s) {
printf("name: %s\n", s->name);
printf("address: %s\n", s->address);
printf("zip: %d\n", s->zip);
}

Passing strings through and array to a struct in C

I'm pretty new to C and I'm not sure what I'm doing. Im trying to create a simple function to create a book. I want to pass two strings in as parameters but I don't know the proper way to access them in C. I have tried many things here is where I am at. Thanks for any help!
#include <stdio.h>
struct book {
char title[50];
char author[50];
};
struct book createBook(char title[50], char author[50]) {
struct book x = { title, author };
return x;
}
You won't be able to initialize the members this way since they're strings.
Use strncpy from string.h:
#include <string.h>
strncpy(x.title, title, 50);
strncpy(x.author, author, 50);
And your declaration would just become:
struct book x;
Use can't initialize variable or members using this way struct book
x = { title, author };
use strcpy() or strncpy() for initializing member variables
strncpy_s(x.title, "Kite Book",sizeof(x.title));
strncpy_s(x.author, "Andre",sizeof(x.author));
or
strcpy(x.title, "Kite Book");
strcpy(x.author, "Andre");
#include <stdio.h>
#include<string.h>
struct book {
char title[50];
char author[50];
};
struct book createBook(char title[50], char author[50]) {
struct book x;
strncpy_s(x.title, "Kite Book",sizeof(x.title));
strncpy_s(x.author, "Andre",sizeof(x.author));
return x;
}
int main()
{
char title[] = { "Kite" };
char author[] = { "Andre" };
createBook(title, author);
return 0;
}

Struct in C. Unknown type name,

I am new to structures in C but as far as I know, my code is "correct". I am using Codeblocks but I've also compiled it in DEV C++ and I got the same error
#include <stdio.h>
#include <stdlib.h>
struct film{
int year;
char title[30];
char director[30];
char main_char[30];
} ;
int main ()
{
film venom={ 2018, "Venom", "Ruben Fleischer", "Tom Hardy" };
printf("Year: %d\n", venom.year);
printf("Title: %s\n", venom.title);
printf("Director: %s\n", venom.director);
printf("Main Character: %s\n", venom.main_char);
system("PAUSE");
return 0;
}
I have not idea what is the error about.
This is C, not C++, so structs have their own namespace.
You need to either write struct film venom;, or use the traditional typedef:
typedef struct film film;
which is often attached to the struct definition itself;
typedef struct film{
int year;
char title[30];
char director[30];
char main_char[30];
} film;
struct film
{
...
} ;
and then
struct film f;
or
typedef struct
{
...
} film;
and then
film f;
Also I would advise you to use "s_" and "t_" to make a difference between the structure and its alias and use the "t_" alias as a type when you declare the structure.
typedef struct s_film {
int year;
char title[30];
char director[30];
char main_char[30];
} t_film;
And then use it the following way:
t_film venom = {2018, "Venom", "Ruben Fleischer", "Tom Hardy"};
You need to use:
struct film venom={ 2018, "Venom", "Ruben Fleischer", "Tom Hardy" };
Or you can typedef the struct
typedef struct {
int year;
char title[30];
char director[30];
char main_char[30];
} film;
Which allows you to use film instead of struct film

I tried to allocate memory using malloc in a structure but it didn't work?Why?

## Code to read general information ##
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
typedef struct{
char *name =(char*)malloc(20);
int age;
int id;
}info;
main()
{
info a;
printf("Enter Name :");
scanf(" %[^\n]",a.name);
a.age=19;
a.id=11700055;
printf("Name :%s\nAge :%d\nId :%d\nSize of info
:%d\n",a.name,a.age,a.id,sizeof(a));
return 0;
}
https://i.stack.imgur.com/WoA0T.png
what is wrong with this code?
it's showing errors i don't understand like info has no member named 'name'?
it also says that name,age,id are not the members of info.
Inside struct declaration you are allocating memory that is not allowed.
If you need array inside of it
typedef struct{
char name[20];
int age;
int id;
}info;
Alternatively you can do this
#define MAXLEN 20
typedef struct{
char* name;
int age;
int id;
}info;
info p;
p.name = malloc(MAXLEN);
if(!p.name){ perror("malloc");exit(1);}
...
It should be int main(void) not main().

Is this a correct/safe way to define and use "interfaces" in pure C

for the past few months I've been trying to code in pure C and avoid C++ as much as I can (for personal reasons, C++ is a nice language in deed), but once in a while there comes situations where I miss some concepts that I used to be using a lot back when I coded in C++, which there is no obvious equivalent in C for them, one of those concepts being "Interface". so after a few hours of research I came up with this solution but I'm afraid that my code might go wrong sometime in the future. Below is the sample code of what I want to do:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef int (*on_affected_cb) (const char *msg);
typedef struct affectee_t affectee_t;
typedef struct type_a_t type_a_t;
typedef struct type_b_t type_b_t;
typedef struct type_c_t type_c_t;
typedef struct owner_t owner_t;
//******************************************************************************
struct affectee_t{ //interface
on_affected_cb on_affected;
};
void affectee_notify(affectee_t* self, const char* msg){
self->on_affected(msg);
}
//******************************************************************************
struct type_a_t{ //implementor a
affectee_t affectee;
int num;
};
static int type_a_on_affected (const char *msg){
printf("this is type a reading msg: %s\n", msg);
return 1000;
}
void type_a_init(type_a_t* self){
self->num = 0;
self->affectee.on_affected = type_a_on_affected;
}
//******************************************************************************
struct type_b_t{ //implementor b
affectee_t affectee;
char name[128];
};
static int type_b_on_affected (const char *msg){
printf("this is type b reading msg: %s\n", msg);
return 2000;
}
void type_b_init(type_b_t* self){
memset(self->name, 0, sizeof(self->name));
self->affectee.on_affected = type_b_on_affected;
}
//******************************************************************************
struct owner_t{ // ordinary struct/class
type_a_t ta;
type_b_t tb;
};
void owner_init(owner_t* self){
type_a_init(&self->ta);
type_b_init(&self->tb);
}
void owner_notify(owner_t* self){
const char msg[] = "what the f...!";
affectee_notify((affectee_t*)&self->ta, msg); //<- pointer casting!!!
affectee_notify((affectee_t*)&self->tb, msg); //<- same here
}
//******************************************************************************
int main(int argc, char **argv){
owner_t owner;
owner_init(&owner);
owner_notify(&owner);
}

Resources