What is the problem here in struct definition and compiler error? - c

When I type the following code:
struct student {
int* grades;
int num_grades;
};
int main()
{
struct student s1 = { { 100, **50**, 74}, 3 }, s2 = { {100, **90**, 80, 90, 90}, 5 }, s3 = { {85, **90**}, 2 };
struct student arr[3] = { s1, s2, s3 };
}
I get two errors error:
C2078 too many initializers
E0146 too many initializer values
I've marked the numbers with two bold asterisks to tell you where the Visual Studio puts red underline.
Does anyone know why the compiler tells me that error?

You cannot initialize a pointer (grades variable) by brace-enclosed initializer list. You need to make use of a compound literal.
Something like
struct student s1 = { (int []){ 100, 50 , 74}, 3 };
should do the job.

Related

How do I initialize a struct containing another struct?

I'm new and i try to create a struct of stuct on C code. I don't understand how i can inizialize a struct of struct. Someneone help me?
I have:
#define SIZEHOSP 200
#define DIM 200
#define SIZESICK 2000
typedef struct SICKREGION {
char firstName[20];
char lastName[20];
char fiscalCode[16];
enum stateSick;
diagnosisDate data;
healingDate dataH;
};
typedef struct HOSPITAL {
char nameHospital[30];
int codeHospital;
char addressHospital[40];
char departmentManager[30];
int beds;
int bedsIntensiveCare;
};
HOSPITAL hospital[SIZEHOSP];
typedef struct REGION {
char nameRegion[20];
int codeRegion;
char MainTownRegion[15];
char namePresidentRegion[20];
int numberHospital;
int numberSickRegion;
HOSPITAL hospital[SIZEHOSP];
SICKREGION sickregion[SIZESICK];
};
REGION region[DIM] = {
{"Sicilia", 0004, "Palermo", "Musumeci", 40, 150},
{"sardegna", 4444, "cagliari", "pippo", 200, 50},
{"calabria", 0000, "reggio", "Josh", 12, 18}
};
for example i inizialized 3 type of REGION. but they are incomplete because i don't know how insert the value of structure HOSPITAL and SICKREGION inside the region[DIM]. What is the syntax? I hope he explained the problem well.
How do I initialize a struct containing another struct?
There are several ways to initialize a struct. To simplify, the following example uses smaller structs than those you provided...
The following will illustrate initialization with initialization with values ( = {,,,{,,}}; ), then with zeros = {0} :
typedef struct {
int count;
float cash;
char item[50];
}Purchase;
typedef struct {
int accnt;
char acct_name[50];
Purchase purch;
} Acct;
Acct acct = {100123, "Robert Baily", {15, 12.50, "Tires"}};
//Or, using member names to self document the initialization statement as suggested in comments:
Acct acct1 = Acct acct = {.accnt=100123, .acct_name="Robert Baily", {.count=15, .cash=12.50, .item="Tires"}};
Acct acct2 = {0};
int main(void)
{
printf("acct = %d\nAcct_name = %s\nitem = %s\ncount = %d\ncash = %3.2f\n", acct.accnt, acct.acct_name, acct.purch.item, acct.purch.count, acct.purch.cash);
printf("acct2 = %d\nAcct_name = %s\nitem = %s\ncount = %d\ncash = %3.2f\n", acct2.accnt, acct2.acct_name, acct2.purch.item, acct2.purch.count, acct2.purch.cash);
return 0;
}
Although these are small, they illustrate what you are doing with your larger, more complicated structs. I suggest that for your structs it will be extremely tedious, and probably not necessary to use the first method. struct declaration in an actual program is often initialized by zeroing. i.e. {0}

initializing array of pointers to structs

How do I initialize an array of structs without creating intermediate array of list of pointers to these structs? Consider the following example code:
snippets $ cat a2p.c
struct shape {
int angles;
char shape_name[16];
};
typedef struct shape shape_t;
struct container {
char name[32];
shape_t **elements;
int num_elts;
};
typedef struct container container_t;
shape_t triangle = {
.angles = 3,
.shape_name = {"Triangle"}
};
shape_t rectangle = {
.angles = 4,
.shape_name = {"Rectangle"}
};
container_t c = {
.name = {"Case"},
.elements = {
&triangle,
&rectangle
},
.num_elts =2
};
int main(void) {
return 0;
}
I need the .elements member to point to an array of pointers to shape_t sturcts, but this code does not compile:
snippets $ gcc -c a2p.c
a2p.c:24:2: warning: braces around scalar initializer
.elements = {
^
a2p.c:24:2: note: (near initialization for ‘c.elements’)
a2p.c:25:3: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
&triangle,
^
a2p.c:25:3: note: (near initialization for ‘c.elements’)
a2p.c:26:3: warning: excess elements in scalar initializer
&rectangle
^
a2p.c:26:3: note: (near initialization for ‘c.elements’)
snippets $
However , if I add an intermediate array , like this:
shape_t *shapes[] = {
&triangle,
&rectangle
};
container_t c = {
.name = {"Case"},
.elements = shapes,
.num_elts =2
};
The code compiles ok. Can I avoid creating the shapes[] array as an intermediate step and directly initialize container_t with all data like on the first code snippet? What would be the correct initialization syntax then?
You are almost there; you just need to ensure that the elements initializer is a suitable pointer, like this:
struct shape {
int angles;
char shape_name[16];
};
typedef struct shape shape_t;
struct container {
char name[32];
shape_t **elements;
int num_elts;
};
typedef struct container container_t;
shape_t triangle = {
.angles = 3,
.shape_name = { "Triangle" }
};
shape_t rectangle = {
.angles = 4,
.shape_name = { "Rectangle" }
};
container_t c = {
.name = { "Case" },
.elements = (shape_t *[]) {
&triangle,
&rectangle,
},
.num_elts = 2,
};
int main(void) {
return 0;
}
Note the use of a compound literal for the array of pointers to shape_t elements.
You have to do it exactly like you did it in your second snippet. The only way you can do it all in one initialization (as in your original code) is if you declare elements as an array of shape_t *, as in shape_t *elements[10], but you probably don't want to have a fixed size array there.
If you move elements member to the END of the structure DEFINITION you can then use the following on C99, and later, compilers:
container_t c2 = {
.name = {"Case2"},
.num_elts =3,
.elements = {
&(shape_t){ 3, "Triangle" } ,
&(shape_t){ 4, "Rectangle" },
&(shape_t){ 2, "Line" }
}
};
The variable size member must be the last member of the structure.
The part of me that hates places for easy bugs notes you can get rid of the need for a manually set element count by ending the list with a NULL pointers and dropping num_elts:
container_t c2 = {
.name = {"Case2"},
.elements = {
&(shape_t){ 3, "Triangle" } ,
&(shape_t){ 4, "Rectangle" },
&(shape_t){ 2, "Line" },
NULL
}
};
Now you just step through the list until NULL == container_list->elements[n]

How do I create an Array of Objects in C?

I'm new to C, coming from a language like javascript the amount of types, keywords etc. in the language are painfully confusing.
In javascript I can create an array of objects like so.
arrayOfObjectsInsideJavascript = [
{ s:"ejf09j290fj390j2f09", f=0 },
{ s:"dj320992209920209dj", f=0 }
]
From what I've read it seems that I'll need to be using typedefand orstructs.
I've tried:
typedef struct[] = {
{ s:"ejf09j290fj390j2f09", f=0 },
{ s:"dj320992209920209dj", f=0 }
}
struct[] = {
{ s:"ejf09j290fj390j2f09", f=0 },
{ s:"dj320992209920209dj", f=0 }
}
typedef struct {
char[] s = "ejf09j290fj390j2f09";
int f = 0;
} objectLikeClassThingy;
What's the best way to create the object I need?
like this ?
struct {
const char *s;
double f;
} obj[] = {
{ .s = "ejf09j290fj390j2f09", .f = 0 },
{ .s = "dj320992209920209dj", .f = 0 }
};
Where JavaScript has dynamic "properties", C has static "tags". A struct type is defined as a sequence of tags, which each have a type.
For the type inside your example array
arrayOfObjectsInsideJavascript = [
{ s:"ejf09j290fj390j2f09", f=0 },
{ s:"dj320992209920209dj", f=0 }
]
your last solution started off almost correctly:
struct element {
char s[256];
int f;
};
You have two options for the type of s:
If you want to store the string inside the object, you use some array type, such as char s[256]. 256 is the length of the array, so when you use zero-terminated strings, the maximum allowed string length is 255 (which is 256, minus one for the '\0' character).
If you want to store the string outside the object, you use some pointer type. Since you want to use string literals, you should declare the tag as const char *s. Changing a string literal causes undefined behaviour, so it's best to prevent yourself from doing so.
For this answer, I'll use the first option in the examples.
If you want to define one struct, you could now write something like
struct element {
char s[256];
int f;
} one_object = {
.s = "ejf09j290fj390j2f09",
.f = 0,
};
or
struct element {
char s[256];
int f;
};
/* ... later, in a scope where `struct element` is visible ... */
struct element one_object = {
.s = "ejf09j290fj390j2f09",
.f = 0,
};
or, with a typedef,
typedef struct {
char s[256];
int f;
} your_element_type;
/* ... later, in a scope where `your_element_type` is visible ... */
your_element_type one_object = {
.s = "ejf09j290fj390j2f09",
.f = 0,
};
Note that this doesn't necessarily work with older compilers that don't support the C99 standard. In the older days, you'd have to initialise fields in order:
your_element_type one_object = { "ejf09j290fj390j2f09", 0 };
Also note that, if you're never going to refer to the type name struct element again, you don't have to name it:
struct {
char s[256];
int f;
} one_object = {
.s = "ejf09j290fj390j2f09",
.f = 0,
};
Arrays are initialised similarly (you've actually already initialised an array, namely s, with a string):
struct element {
char s[256];
int f;
} so_many_objects[] = {
{ .s = "ejf09j290fj390j2f09", .f = 0 },
{ .s = "dj320992209920209dj", .f = 0 },
};
or
struct element {
char s[256];
int f;
};
/* ... later, in a scope where `struct element` is visible ... */
struct element so_many_objects[] = {
{ .s = "ejf09j290fj390j2f09", .f = 0 },
{ .s = "dj320992209920209dj", .f = 0 },
};
or, with a typedef again,
typedef struct {
char s[256];
int f;
} your_element_type;
/* ... later, in a scope where `your_element_type` is visible ... */
your_element_type so_many_objects[] = {
{ .s = "ejf09j290fj390j2f09", .f = 0 },
{ .s = "dj320992209920209dj", .f = 0 },
};
By the way, note that we are using an incomplete type for so_many_objects; this is only possible because the compiler can see how big the array should be. In these examples, the compiler would treat your code as if you'd have written struct element so_many_objects[2]. If you think you'll have to extend the array with more objects, you'd better specify how many elements the array has (at maximum), or learn about dynamic allocation.

How to print out the members of a struct, weird errors?

I've been trying to print of the members of a struct I have created, however there are a few declarations errors that are showing saying my structs are undeclared. I have a separate function for printing the members of the struct. I have no idea on how to debug it... please help
I have errors such as game1- undeclared (first use in this function) and expected = , ; asm or attribute before { token
#include <stdio.h>
#include <stdlib.h>
struct video_game
{
char *name, *genre, *developer, *platformer, *app_purchase;
int release_year, age_limit;
float price;
};
void print_video_game_details(struct video_game* s)
{
printf("\nTitle: %s\n", s->name);
printf("Genre: %s\n", s->genre);
printf("Developer: %s\n", s->developer);
printf("Year of Release: %d\n", s->release_year);
printf("Lower Age Limit: %d\n", s->age_limit);
printf("Price: $%f\n", s->price);
printf("In-app Purchase: %s\n", s->app_purchase);
}
int main(int agrc, char* agrv[])
{
struct video_game game1
{
game1.name = "Candy Crush Saga";
game1.genre = "Match-Three Puzzle";
game1.developer = "King";
game1.release_year = 2012;
game1.platform = "Android, iOS, Windows Phone";
game1.age_limit = 7;
game1.price = 0.00;
game1.app_purchase = "Yes";
};
struct video_game game2
{
game2.name = "Halo 4";
game2.genre = "First Person Shooter";
game2.developer = "343 Industries";
game2.release_year = 2014;
game2.platform = "Xbox 360, Xbox One";
game2.age_limit = 16;
game2.price = 69.95;
game2.app_purchase = "No";
};
struct video_game game1
{
game3.name = "Uncharted 2: Among Thieves";
game3.genre = "Action adventure RPG";
game3.developer = "Naughty Dog";
game3.release_year = 2012;
game3.platform = "PS3";
game3.age_limit = 16;
game3.price = 30.00;
game3.app_purchase = "No";
};
print_video_game_details(&game1);
print_video_game_details(&game2);
print_video_game_details(&game3);
return 0;
}
Your instance creations (game1, game2 and game3) are not C, they are using some made-up syntax.
They should be something like
struct video_game game1 = {
.name = "Candy Crush Saga",
/* ... */
};
You need to define three variables of type struct video_game, and <type> <name> [= <initializer>] is (roughly) how variables are defined in C.
If you don't have C99, it must be:
struct video_game game1 = {
"Candy Crush Saga",
"Match-Three Puzzle",
"King",
"Android, iOS, Windows Phone",
"Yes",
2012,
7,
0.00
};
Things to notice, that you seem to be ignoring:
No names of fields inside the initializer, just values.
The order must be exactly the same as when the struct was declared; first five strings, then two integers, then a float.
Values are separated with commas, not semicolons.

Passing array of struct with typedef to a function

I need help with C programming. I have the following situation:
struct Product {
int code;
char *name;
char *spec;
int quantity;
float price;
};
typedef struct Product products[8];
products product = {
{100, "Mouse", "Ottico", 10, 8.30},
{101, "Tastiera", "Wireless", 6, 15.50},
{102, "Monitor", "LCD", 3, 150.25},
{103, "Webcam", "USB", 12, 12.00},
{104, "Stampante", "A Inchiostro", 6, 100.00},
{105, "Scanner", "Alta Risoluzione", 9, 70.50},
{106, "Router", "300 Mbps", 10, 80.30},
{107, "Lettore Mp3", "10 GB", 16, 100.00}
};
Please disregard the use of Italian language above.
I would like to pass the array of structs named "product" to a function. For example, if I wanted to do something like
product[1].name = "Computer"
But inside of a function, how am I supposed to do it? I would like to know how to call that function from the main() and how to write the prototype in my header file.
Thanks in advance for any help.
EDIT
I'm giving you this test program. This one ain't working and there is not even call to function in the main. It just doesn't compile.
#include <stdio.h>
#include <stdlib.h>
void test(Card *card);
int main()
{
struct Card {
char *type;
char *name;
};
typedef struct Card cards[2];
cards card = {{"Hi", "Hi"}, {"Foo", "Foo"}};
return 0;
}
void test(Card *card) {
printf("%s", card[1].type);
}
Here:
void foo(struct Product *bla)
{
bla[1].name = "Computer";
}
or using your type alias
void foo(products bla)
{
bla[1].name = "Computer";
}
then call the function like this:
foo(product);
Since you have the typedef (which is missing a struct keyword in your example, by the way), you can just use that type in the function prototype:
void func(products p);
A function performing the specific operation you asked about might be:
void func(products p)
{
p[1].name = "Computer";
}
You can call it like:
func(product);
From anywhere where product is in scope.
typedef struct tag_Product {
int code;
char *name;
char *spec;
int quantity;
float price;
} PRODUCT;
PRODUCT products[8] = {
{100, "Mouse", "Ottico", 10, 8.30},
{101, "Tastiera", "Wireless", 6, 15.50},
{102, "Monitor", "LCD", 3, 150.25},
{103, "Webcam", "USB", 12, 12.00},
{104, "Stampante", "A Inchiostro", 6, 100.00},
{105, "Scanner", "Alta Risoluzione", 9, 70.50},
{106, "Router", "300 Mbps", 10, 80.30},
{107, "Lettore Mp3", "10 GB", 16, 100.00}
};
void MyFunction(PRODUCT *pProduct)
{
pProduct->code = 0; // sample
}
void main()
{
MyFunction(&products[2]); // sample
}

Resources