How to initialise an anonymous union within a struct in c - c

I want to initialise all three arrays of mainstr , can anyone help me to initialise this anonymous union inside the struture? 0th index should initialise with interger array and 1st and 2nd indexes with char pointer.
typedef struct
{
int testy;
union
{
int a[3];
char* b[3];
}
bool testz;
} testStr;
typedef struct
{
testStr x[3];
} mainStr;
something like this,
mainStr test = {
{20, {{10, 20, 30}}, FALSE},
{10, {{"test1", "test2", NULL}}, TRUE},
{30, {{"test3", "test4", NULL}}, FALSE},
}

Use designators:
mainStr test = {{
{20, {{10, 20, 30}}, false},
{10, {.b={"test1", "test2", NULL}}, true},
{30, {.b={"test3", "test4", NULL}}, false},
}};
Demo

A bit of work, but do-able.
#include <stdbool.h>
int foo() {
typedef struct {
int testy;
union {
int a[3];
char *b[3];
};
bool testz;
} testStr;
typedef struct {
testStr x[3];
} mainStr;
testStr test1 = {20, { {10, 20, 30}}, false};
(void) test1;
mainStr test = { //
{ //
{20, { {10, 20, 30}}, false}, //
{10, { .b={"test1", "test2", NULL}}, true}, //
{30, { .b={"test3", "test4", NULL}}, false} //
}//
};
(void) test;
}

Some issues:
union { ... }; must end with semicolon.
Use standard bool not some home-made version.
mainStr Means there's a need for an extra pair of initializers, one for the struct, one for the array member x.
With those issues fixed, you can use designated initializers to tell the compiler which union member you are initializing:
#include <stdbool.h>
typedef struct {
int testy;
union {
int a[3];
char* b[3];
};
bool testz;
} testStr;
typedef struct {
testStr x[3];
} mainStr;
int main (void) {
mainStr test =
{
{
{20, .a = {10, 20, 30}, false},
{10, .b = {"test1", "test2", 0}, true},
{30, .b = {"test3", "test4", 0}, false},
}
};
}
It might be a good idea to use designated initializers for all struct/union members though, to get self-documenting code.

Related

near initialization structure warning

I'm genuinly confused as to why i am having this error. My code compiles fine but i would prefer to have 0 warnings. After searching stackoverflow for a bit no one had the same structure type that i was using. Below is a snippit of my code (these are made up names)
if it helps my MAXCONTACTS is set to 5
struct Contact conNum[MAXCONTACTS] = { { {"Rick", { '\0' }, "Grimes" },
{11, "Trailer Park", 0, "A7A 2J2", "King City" },
{"4161112222", "4162223333", "4163334444" } },
{
{"Maggie", "R.", "Greene" },
{55, "Hightop House", 0, "A9A 3K3", "Bolton" },
{"9051112222", "9052223333", "9053334444" } },
{
{"Morgan", "A.", "Jones" },
{77, "Cottage Lane", 0, "C7C 9Q9", "Peterborough"},
{"7051112222", "7052223333", "7053334444" } },
{
{"Sasha", {'\0'}, "Williams" },
{55, "Hightop House", 0, "A9A 3K3", "Bolton"},
{"9052223333", "9052223333", "9054445555" } },
};
edit: here is my structure declaration
// Structure type Name declaration
struct Name {
char firstName[31];
char middleInitial[7];
char lastName[36];
};
struct Address {
int streetNumber;
int apartmentNumber;
char street[41];
char postalCode[8];
char city[41];
};
struct Numbers {
char cell[11];
char home[11];
char business[11];
};
struct Contact {
struct Name name;
struct Address address;
struct ``Numbers numbers;
};
Your struct Address contains two int fields followed by two char arrays:
struct Address {
int streetNumber;
int apartmentNumber;
char street[41];
char postalCode[8];
char city[41];
};
but you don't initialize them in that order:
{11, "Trailer Park", 0, "A7A 2J2", "King City" },
Unless you use named initializers, fields must be specified in order. Put the street number first, then the apartment number, then the street:
{11, 0, "Trailer Park", "A7A 2J2", "King City" },
Do the same with the other three.
{11, "Trailer Park", 0, "A7A 2J2", "King City" },
this initialization is for
struct Address {
int streetNumber;
int apartmentNumber;
char street[41];
char postalCode[8];
char city[41];
};
As you see you are trying to initialize "Trailer Park" to int apartmentNumber;.
That is why you are getting warning.
Thus change the definition of structure to
struct Address {
int streetNumber;
char street[41];
int apartmentNumber;
char postalCode[8];
char city[41];
};
At only one place
or
change the initialization sequence like below in all the places.
{11, 0, "Trailer Park", "A7A 2J2", "King City" },

Retrieve value from array inside of another array [C]

Take a look at this array:
const int *c000[64][1][3] =
{
//Row 1
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 2
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 3
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 4
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 5
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 6*
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 7
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
//Row 8
{ {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} }, { {0, 0, 0} },
};
Ignore the strange size and structure of the array, that's not what is important. I need to be able to use an array inside this array. For example, I have an array called h002:
const int h002[18] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0xe0, 0xe0}; //01
I need to be able to use h002 from inside c000. Such as:
{ {h002, 0, 0} },
This compiles just fine, however
myVar = c000[0][0][0];
retrieves the address of h002. I need the first item in h002, not the address. I'm confused as to why it would even give me the adress of h002 at all? I would imagine *h002 would retrieve the address, but then that doesn't compile at all.
I have seen several questions on SO that closely resemble mine, such as this one:
Creating an array of int arrays in C?
I have tried that particular example above. It works when I have it in my main.c file, but when I try it in the same .c file that c000 and h002 are contained in, it fails to compile. Perhaps this has something to do with it? I'm not sure why it would, considering using h002 inside c000 returns the address of h002 just fine. It's strange that the code presented in the link above wouldn't compile outside of my main file.
I feel like I'm making some kind of obvious, little mistake. I've been messing around with this off and on for about 5 days now. Trial and error and research has gotten me nowhere. Researching was difficult enough, as there doesn't seem to be much on using arrays like this, and none of my findings significantly helped me.
Feel free to ask questions. I'll be glad to specify more information if needed.
EDIT: Thanks so much to Stephan Lechner for helping me solve my issue. To get the result I needed, I had to do
myVar = *(c000[0][0][0]);
This works perfectly. I can also add whatever number I like at the end to retrieve different indexes in h002. For example:
myVar = *(c000[0][0][0] + 7);
Hope this helps someone out in the future.
I think the basic misunderstanding is the meaning of const int *c000[64][1][3], which denotes a three dimensional array of pointers to int, but not a pointer to an 3D-array of integers. To demonstrate this, consider the following simplified examples together with compiler warnings:
int aSingleIntValue = 10; // integer value
int *aSinglePtrToIntValue = &aSingleIntValue; // pointer to an integer value
// 1D-array of integer values
int oneDArrayOfInt[5] = { 3,4,5,6,7 };
// 1D-array of pointers to int; Note: OK, since 0 is interpreted as NULL
int *oneDArrayOfIntPtrOK[5] = { aSinglePtrToIntValue,0,0,0,0 };
// 1D-array of pointers to int; Note: 3,4,.. are int values, not pointers to int; Hence compiler complains:
// Warning: Incompatible integer to pointer conversion initializing "int *" with an expression of type "int"
int *oneDArrayOfIntPtrWarning[5] = { 3,4,5,6,7 };
// 3D-array of pointers to int; Note: OK, since 0 is interpreted as NULL
int *threeDArrayOfIntPtrOK[5][5][5] = { { { aSinglePtrToIntValue,0,0 }, { 0,0,0} } };
// 3D-array of pointers to int; Warining: Incompatible integer to pointer conversion initializing "int *" with an expression of type "int"
int *threeDArrayOfIntPtrWarning[5][5][5] = { { { 3,4,5 }, { 2,3,1} } };
Just for showing a different meaning: if one would like to declare a pointer to an array of 5 integers, this could be expressed as follows:
typedef int arrayOf5Int_t[5];
arrayOf5Int_t *arrayOf5IntPtr = &oneDArrayOfInt;
Given that, let's explain the meaning of
const int h002[18] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0xe0, 0xe0};
const int *c000[64][1][3] = { { { h002, 0, 0 } } };
Note that an element of c000 is a pointer to an integer, and note that variable h002 used in the context of the array initialiser decays to a pointer to an integer (pointing to the first element of h002). This is pretty much the same as declaring const int* ptrToH002 = h002, and the following print out demonstrates that this is actually the same:
const int *elemAt0x0x0 = c000[0][0][0];
const int *ptrToH002 = h002;
int isTheSame = elemAt0x0x0 == ptrToH002;
printf("pointer elemAt0x0x0 == ptrToH002 is %s", (isTheSame ? "true" : "false"));
// Prints: pointer elemAt0x0x0 == ptrToH002 is true
Hence, it should be clear that myVar = c000[0][0][0] retrieves an address, and not an integer value or an integer array. The address points to the first element of array h002.
Example of multidimensional array:
int main(){
int a1[] = {1,2,3,4};
int a2[] = {5,6,7,8};
int a3[] = {9,10,11,12};
int * superArr[3] = {a1,a2,a3};
printf("%d\n", superArr[2][1]);
}
You should be able to change your code to what you need using this example.

printing items in an array won't print the items

#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 20
struct Item
{
int SKU;
char name[MAX_LENGTH+1];
};
int contains(void)
{
int compare;
return 0;
}
void displayItemWith(struct Item item[], int count)
{
int i;
char alphabet;
i = 0;
for(i=0; i<count; i++){
//char inventory[ ] = {item->SKU};
printf("%d", item[i].SKU);
}
int main(void)
{
int compare;
char count;
//prints the title
printf("=== TEST ===\n");
// hard-coded inventory 21 items - room for 0 more
struct Item inventory[21] =
{
// price sku txd qty min name
{ .SKU = 275, "Royal Gala Apples" },
{ .SKU = 386, "Honeydew Melon" },
{ .SKU = 240, "Blueberries" },
{ .SKU = 916, "Seedless Grapes" },
{ .SKU = 385, "Pomegranate" },
{ .SKU = 495, "Banana" },
{ .SKU = 316, "Kiwifruit" },
{ .SKU = 355, "Chicken Alfredo" },
{ .SKU = 846, "Veal Parmigiana" },
{ .SKU = 359, "Beefsteak Pie" },
{ .SKU = 127, "Curry Chicken" },
{ .SKU = 238, "Tide Detergent" },
{ .SKU = 324, "Tide Liq. Pods" },
{ .SKU = 491, "Tide Powder Det." },
{ .SKU = 538, "Lays Chips S&V" },
{ .SKU = 649, "Joe Org Chips" },
{ .SKU = 731, "Allen's Apple Juice" },
{ .SKU = 984, "Coke 12 Pack" },
{ .SKU = 350, "Nestea 12 Pack" },
{ .SKU = 835, "7up 12 Pack" }
};
printf("*** NO MATCHES ***\n");
printf("=== END ===\n");
return 0;
}
Hello, users, I am trying to print out the list of items
in output with such format;
SKU: 275 - Royal Gala Apples
SKU: 386 - Honeydew Melon
but the only thing that would print is the ===TEST===, NO MATCHES, ===END===.
Any reason why?
Because no matter what you do, the "NO MATCHES" will show because you printf it without no conditions. Also, in order to print the list you need to call the method you made which is "displayItemWith(struct Item item[], int count)" and please declare the struct first for a better approach.example:
struct Books {
char title[50];
char author[50];
char subject[100];
int book_id;
};

Expected identifier or "(" on Xcode 4.3.3

on the line " int RandomA, RandomB" I keep on getting an error. The error says Expected identifier or "(". The same error also pop up between the struct card and the name of the cards. I'm not sure how to fix it. This is my first time asking a question on this website. I'm using mac osx application command line tool.
main.c file
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct card {
char* name;
char* suit;
int value;
};
void shuffle(struct card* deck){
// Seed the random number generator
srandom(time (NULL ) );
int i = 0;
int randomA, randomB;
struct card tempCard;
do {
// Generate 2 random numbers to determine which cards to swap
randomA = random() % 52;
randomB = random() % 52;
// Swap slots A and B
tempCard = deck[randomA];
deck[randomA] = deck[randomB];
deck[randomB] = tempCard;
// Increment the counter
++i;
}
while (i<1000000);
}
void printDeck(struct card* deck){
// Print out the shuffled deck
int i=0;
while (i<52) {
if (deck[i].value == 1) {
printf("The ace of %s is great!\n", deck[i].suit);
}
else {
switch (deck[i].value){
case 11:
printf("A Jack of all trades (%s)\n",deck[i].suit);
break;
case 12:
printf("A Queen of the castle (%s)\n",deck[i].suit);
break;
case 13:
printf("The King of the world (%s)\n",deck[i].suit);
break;
default:
printf("The card is %s of %s\n", deck[i].name,deck[i].suit);
break;
}
}
i++;
}
}
int main(int argc, const char * argv[]);
{
struct card deck[] =
{
{"ace", "spades", 1}, {"two", "spades", 2}, {"three", "spades", 3},
{"four", "spades", 4}, {"five", "spades", 5}, {"six", "spades", 6},
{"seven", "spades", 7}, {"eight", "spades", 8}, {"nine", "spades", 9},
{"ten", "spades", 10}, {"jack", "spades", 11}, {"queen", "spades", 12},
{"king", "spades", 13},
{"ace", "clubs", 1}, {"two", "clubs", 2}, {"three", "clubs", 3},
{"four", "clubs", 4}, {"five", "clubs", 5}, {"six", "clubs", 6},
{"seven", "clubs", 7}, {"eight", "clubs", 8}, {"nine", "clubs", 9},
{"ten", "clubs", 10}, {"jack", "clubs", 11}, {"queen", "clubs", 12},
{"king", "clubs", 13},
{"ace", "hearts", 1}, {"two", "hearts", 2}, {"three", "hearts", 3},
{"four", "hearts", 4}, {"five", "hearts", 5}, {"six", "hearts", 6},
{"five", "hearts", 7}, {"eight", "hearts", 8}, {"nine", "hearts", 9},
{"ten", "hearts", 10}, {"jack", "hearts", 11}, {"queen", "hearts", 12},
{"king", "hearts", 13},
{"ace", "diamonds", 1}, {"two", "diamonds", 2}, {"three", "diamonds", 3},
{"four", "diamonds", 4}, {"five", "diamonds", 5}, {"six", "diamonds", 6},
{"seven", "diamonds", 7}, {"eight", "diamonds", 8},
{"nine", "diamonds", 9}, {"ten", "diamonds", 10}, {"jack", "diamonds", 11},
{"queen", "diamonds", 12},{"king", "diamonds", 13}};
// Run the function to shuffle the deck
shuffle(deck);
// Print the deck
printDeck(deck);
return 0;
}
Perhaps this:
int main(int argc, const char * argv[]) /* -------> */ ; /* <------- */
Followed by {, which opens up a scope outside of a context...

how to initialize members of an array of struct in C

I have the following struct:
typedef struct {
int someArray[3][2];
int someVar;
} myStruct;
If I create an array of this struct in my main (like the following), how would I initialize it?
int main() {
myStruct foo[5];
}
I want to initialize the above array of struct in a way similar to initilazing a normal array (see below):
int main() {
int someArray[5] = {1,4,0,8,2};
}
Work from the outside in. You know you have an array of 5 things to initialize:
mystruct foo[5] = {
X,
X,
X,
X,
X
};
where X is a stand-in for initializers of type mystruct. So now we need to figure out what each X looks like. Each instance of mystruct has two elements, somearray and somevar, so you know your initializer for X will be structured like
X = { Y, Z }
Substituting back into the original declaration, we now get
mystruct foo[5] = {
{ Y, Z },
{ Y, Z },
{ Y, Z },
{ Y, Z },
{ Y, Z }
};
Now we need to figure out what each Y looks like. Y corresponds to an initializer for a 3x2 array of int. Again, we can work from the outside in. You have an initializer for a 3-element array:
Y = { A, A, A }
where each array element is a 2-element array of int:
A = { I, I }
Subsituting back into Y, we get
Y = { { I, I }, { I, I }, { I, I } }
Substituting that back into X, we get
X = { { { I, I }, { I, I }, { I, I } }, Z }
which now gives us
mystruct foo[5] = {
{ { { I, I }, { I, I }, { I, I } }, Z },
{ { { I, I }, { I, I }, { I, I } }, Z },
{ { { I, I }, { I, I }, { I, I } }, Z },
{ { { I, I }, { I, I }, { I, I } }, Z },
{ { { I, I }, { I, I }, { I, I } }, Z }
};
Since Z is a stand-in for an integer, we don't need to break it down any further. Just replace the Is and Zs with actual integer values, and you're done:
mystruct foo[5] = {
{{{101, 102}, {201, 202}, {301, 302}}, 41},
{{{111, 112}, {211, 212}, {311, 312}}, 42},
{{{121, 122}, {221, 222}, {321, 322}}, 43},
{{{131, 132}, {231, 232}, {331, 332}}, 44},
{{{141, 142}, {241, 242}, {341, 342}}, 45}
};
Wrap the initializer for each structure element of the array in a set of braces:
myStruct foo[5] =
{
{ { { 11, 12 }, { 13, 14 }, { 55, 56 }, }, 70 },
{ { { 21, 22 }, { 23, 24 }, { 45, 66 }, }, 71 },
{ { { 31, 32 }, { 33, 34 }, { 35, 76 }, }, 72 },
{ { { 41, 42 }, { 43, 44 }, { 25, 86 }, }, 73 },
{ { { 51, 52 }, { 53, 54 }, { 15, 96 }, }, 74 },
};
Like that:
int main() {
// someArr initialization | someVar initialization
mystruct foo[5] = { { { {1, 2}, {1,2}, {1, 2} }, 1 }, // foo[0] initialization
//...
};
}

Resources