Related
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.
#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;
};
I am getting some confusing behaviour trying to use the c builtin bsearch on an array of strings in C. Here is the code. I know you can use the builtin strcmp for searching arrays of strings, but I included myStrCmp for debugging purposes because I didn't know why it wasn't working.
const char *stateNames[] = {"Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "Washington DC", "West Virginia", "Wisconsin", "Wyoming"};
int myStrCmp(const void *s1, const void *s2) {
printf("myStrCmp: s1(%p): %s, s2(%p): %s\n", s1, (char *)s1, s2, (char *)s2);
return strcmp(s1, s2);
}
int determineState(char *state) {
printf("state: %s\n", state);
for(int i = 0; i < 51; i++)
printf("stateNames[%i](%p): %s\n", i, &(stateNames[i]), stateNames[i]);
char *found = (char *) bsearch(state, stateNames, 51, sizeof(char *), myStrCmp );
if(found == NULL)
return -1;
return 0;
}
and here is some of the output when this function is called to look for Alabama.
stateNames[0](0x618440): Alabama
stateNames[1](0x618448): Alaska
stateNames[2](0x618450): Arizona
...
stateNames[24](0x618500): Missouri
stateNames[25](0x618508): Montana
stateNames[26](0x618510): Nebraska
stateNames[27](0x618518): Nevada
stateNames[28](0x618520): New Hampshire
stateNames[29](0x618528): New Jersey
stateNames[30](0x618530): New Mexico
stateNames[31](0x618538): New York
stateNames[32](0x618540): North Carolina
stateNames[33](0x618548): North Dakota
stateNames[34](0x618550): Ohio
stateNames[35](0x618558): Oklahoma
stateNames[36](0x618560): Oregon
stateNames[37](0x618568): Pennsylvania
stateNames[38](0x618570): Rhode Island
stateNames[39](0x618578): South Carolina
stateNames[40](0x618580): South Dakota
stateNames[41](0x618588): Tennessee
stateNames[42](0x618590): Texas
stateNames[43](0x618598): Utah
stateNames[44](0x6185a0): Vermont
stateNames[45](0x6185a8): Virginia
stateNames[46](0x6185b0): Washington
stateNames[47](0x6185b8): Washington DC
stateNames[48](0x6185c0): West Virginia
stateNames[49](0x6185c8): Wisconsin
stateNames[50](0x6185d0): Wyoming
myStrCmp: s1(0x415430): Alabama, s2(0x618508):
UA
myStrCmp: s1(0x415430): Alabama, s2(0x618570): A
myStrCmp: s1(0x415430): Alabama, s2(0x618540): PUA
myStrCmp: s1(0x415430): Alabama, s2(0x618528): 1UA
myStrCmp: s1(0x415430): Alabama, s2(0x618538): GUA
myStrCmp: s1(0x415430): Alabama, s2(0x618530): <UA
As you can see, the locations visited by bsearch in the course of its search should have valid strings (as was just checked before calling bsearch), but the output if you try to print the char * at that location is garbage. Can anyone see my mistake? Incidentally I get the same bad behaviour (but don't get to follow it as closely obviously) when I call bsearch with the final parameter set to:
(int(*)(const void*, const void*))strcmp
Thanks!
Since you are using an array of const char *, bsearch() will pass to the comparison function a pointer to those elements. In other words, it will receive const char * const * in its second argument.
int myStrCmp(const void *s1, const void *s2) {
const char *key = s1;
const char * const *arg = s2;
printf("myStrCmp: s1(%p): %s, s2(%p): %s\n", s1, key, s2, *arg);
return strcmp(key, *arg);
}
Your state name (or key) needs to be a pointer to a pointer. Didn't have to add/remove constanywhere. myStrCmpneeds to dereference by one to compare the strings. The code below does what you want I think. Please let me know if not, thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *stateNames[] = {"Alabama", "Alaska", "Arizona", "Arkansas","California", "Colorado", "Connecticut", "Delaware", "Florida","Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "Washington DC", "West Virginia", "Wisconsin", "Wyoming"};
int myStrCmp(const void *s1, const void *s2) {
printf("myStrCmp: s1(%p): %s, s2(%p): %s\n", s1, *(char **)s1, s2, *(char**)s2);
return strcmp(*(char **) s1, *(char **) s2);
}
int determineState(char *state) {
printf("state: %s\n", state);
for(int i = 0; i < 51; i++)
printf("stateNames[%i](%p): %s\n", i, &(stateNames[i]), stateNames[i]);
char **found = (char **) bsearch(&state, stateNames, 51, sizeof(char *), myStrCmp );
if(found == NULL){
return -1;
} else {
printf("Found it!: %s\n", *found);
}
return 0;
}
int main(int argc, const char * argv[]) {
determineState("Alabama");
}
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...
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
//...
};
}