typedef struct default initialization - c++

How's possible to make default initialization for structs?
I'm trying to make default initialization for my struct but I get this error:
error: request for member 'type' in '((CCatManager::cat_shop_item*)this)->CCatManager::cat_shop_item::catAttr', which is of non-class type 'TCategoryAttribute [0]'
..........................
Here is my codes:
enum EMisc
{
CAT_MAX_NUM = 8,
};
typedef struct TCategoryAttribute
{
BYTE type;
short value;
} TCategoryAttribute;
typedef struct category_items
{
long price;
DWORD order;
TCategoryAttribute catAttr[CAT_MAX_NUM];
category_items()
{
price = 0;
order = 0;
catAttr.type[0] = 0;
.....
catAttr.type[7] = 0;
catAttr.value[0] = 0;
.....
catAttr.value[7] = 0;
}
} CATEGORY_ITEMS;
"price" and "order" are okay, they work but TCategoryAttribute doesn't work...
I'm really confused... thanks in advance, and I hope the question is right.
It's solved, thanks to #Michael.

That is because type isn't an array, rather, catAttr is. Secondly, there are 3 of them you declared, hence you third item is at index 2. remember, you count from 0. So change this portion of your code to:
category_items()
{
price = 0;
order = 0;
catAttr[0].type = 0;
catAttr[1].type = 0;
catAttr[2].type = 0;
//catAttr[3].type = 0; //you can't hit [3]
catAttr[0].value = 0;
catAttr[1].value = 0;
catAttr[2].value = 0;
//catAttr.value[3] = 0;
}
See full code that compiles (and works) here: http://coliru.stacked-crooked.com/a/abda47415ebb9938
BTW, that typedef is redundant. Just do this instead...
struct TCategoryAttribute
{
BYTE type;
short value;
};

Related

Dynamic array of structs containing a dynamic array of structs

I can't for the life of me figure out how to solve this in c.
I have the following structs:
typedef struct
{
uint8_t index = 0;
DLPageItem_t *pageItems = NULL;
uint8_t pageItemCount = 0;
uint8_t selectedItemIndex = 0;
} DLPage_t;
typedef struct
{
uint8_t index = 0;
void *valuePtr = NULL;
uint16_t tmpValue = 0;
DLItemType_t type = DLITEMTYPE::NOTYPE;
uint8_t row = 0;
uint8_t col = 0;
uint8_t targetPageId = 0;
DLItemAction_t action = DLITEMACTION::EDIT;
bool selectable = false;
bool editing = false;
} DLPageItem_t;
And I want to have a dynamic array of DLPage_t (with realloc) and then be able to anytime add DLPageItem_t to any of the already created DLPage_t array members.
So I tried to have a
DLPage_t *_pages = NULL;
and do
this->_pageCount++;
this->_pages = (DLPage_t*)realloc(this->_pages, this->_pageCount * sizeof(DLPage_t));
Then I'm accessing the "pages" and setting the values like this:
this->_pages[this->_pageCount - 1].index = this->_pageCount - 1;
The function which adds DLPageItem_t structs to a DLPage_t struct member, I do it like this:
this->_pages[pageId].pageItemCount++;
this->_pages[pageId].pageItems = (DLPageItem_t*)realloc(this->_pages[pageId].pageItems, this->_pages[pageId].pageItemCount * sizeof(DLPageItem_t));
I have some very funny business going on so I guess I'm doing something wrong and accessing/overwriting memory where I shouldn't.
Can someone please verify whether what I'm doing is correct? I tried to apply/adapt this to my issue but I just can't figure it out: https://stackoverflow.com/a/15397992
Thanks!

Incomplete type not allowed error for built in array

When i am trying to declare this cursed array it tells me incomplete type not allowed, i have made it myself and when it didn't work for no reason i got the same piece of code from the tutorial i'm following (lessons on a site) and it still didn't work , any help ?
#include <iostream>
enum CardSuit
{
SUIT_CLUB,
SUIT_DIAMOND,
SUIT_HEART,
SUIT_SPADE,
MAX_SUITS
};
enum CardRank
{
RANK_2,
RANK_3,
RANK_4,
RANK_5,
RANK_6,
RANK_7,
RANK_8,
RANK_9,
RANK_10,
RANK_JACK,
RANK_QUEEN,
RANK_KING,
RANK_ACE,
MAX_RANKS
};
struct Card
{
CardRank rank;
CardSuit suit;
};
int main()
{
std::array<Card, 52> deck {};
for (int suit = 0; suit < MAX_SUITS; ++suit)
for (int rank = 0; rank < MAX_RANKS; ++rank)
{
deck[card].suit = static_cast<CardSuit>(suit);
deck[card].rank = static_cast<CardRank>(rank);
++card;
}
return 0;
}
You need to #include <array>
Also:
These are wrong:
deck[card].suit = static_cast<CardSuit>(suit);
deck[card].rank = static_cast<CardRank>(rank);
Indexing (deck[ index ]) should be done using integral types, and card is not declared.
size_t card=0; // add this
for (int suit = 0; suit < MAX_SUITS; ++suit)
for (int rank = 0; rank < MAX_RANKS; ++rank)
{
deck[card].suit = static_cast<CardSuit>(suit);
deck[card].rank = static_cast<CardRank>(rank);
++card;
}

Why is this for loop not correct?

Visual Studio is telling me that this for loop isn't correct.
Error Messages are:
type bool unexpected
ok is undeclared identifier
missing ; before }
infos:
-recordset.Select return a long -MoveNext a bool
for (size_t i = 0, bool ok = recordset.Select(Adress::getSQLStatement() + "Where A05.recid = %ld", i); ok; ok = recordset.MoveNext(), i++) {
at(i).Save(recordset);
}
It's as StenSoft said. But you can define an anonymous structure in the loops first statement, and initialize that.
#include <iostream>
using namespace std;
int main() {
for (struct {size_t i; bool ok;} s = {0, true}; s.ok; ++s.i) {
s.ok = s.i < 10;
cout << s.i;
}
return 0;
}
But IMHO, while it works, it's more trouble than it's worth. Better restructure you code.
First off, you can of course rewrite your loop like so:
{
bool ok = recordset.Select(...);
for (std::size_t i = 0; ok; ok = recordset.MoveNext(), ++i)
{
/* ... */
}
}
But the meta lesson here is that almost all loops are for-loops, and when you think your structure is different, think again. There's probably a rewrite in terms of for-loops that makes your logic clearer. Your present code doesn't distinguish an initial error from a "no more records" error later. With the new code, that's now explicitly possible:
if (bool ok = recordset.select(...))
{
for (std::size_t i = 0; ok; ok = recordset.MoveNext(), ++i) { /* ... */ }
}
else
{
// handle initial error
}
I would probably even get rid of the redundant ok variable:
if (recordset.select(...))
{
for (std::size_t i = 0; ; ++i)
{
/* ... */
if (!recordset.MoveNext()) break;
}
}
else
{
// handle initial error
}

Typeid issues to determine what data is processed

Why does this return false and how can I fix it? I'm trying to make a program that writes data to a file and can read that file back in and display it. Also, there are 3 classes. One is a parent class (MyEmployee not displayed) and the Hourly and Salaried classes are child classes.
for (int i = 0; i < ARRAY_SIZE; i++)
{
MyEmployee* empPtr = payroll[i];
if (typeid(*empPtr) == typeid(Hourly))
{
Hourly* empHPtr = static_cast<Hourly*>(empPtr);
}
else if (typeid(*empPtr) == typeid(Salaried))
{
Salaried* empSPtr = static_cast<Salaried*>(empPtr);
}
}
for (int i = 0; i < ARRAY_SIZE; i++)
{
payroll[i]->writeData(myWrittenFile);
}
I'm going to guess that your class hierarchy is:
struct MyEmployee { virtual ~MyEmployee() {}; /* ... */ };
struct Hourly : MyEmployee { /* ... */ };
struct Salaried : MyEmployee { /* ... */ };
If so, then you could replace your code with:
MyEmployee *empPtr = payroll[i];
Hourly *empH = dynamic_cast<Hourly *>(empPtr);
Salaried *empS = dynamic_cast<Salaried *>(empPtr);
The empH and empS will be null if the object was not of that type; and a valid pointer if it was of that type.
Of course, it may be better to replace this whole thing with a virtual function, as chris suggested.
If MyEmployee is polymorphic use dynamic_cast < type-id > ( expression )
This Converts the operand expression to an object of type type-id and will return 0 if the conversion fails.
MyEmployee* empPtr = payroll[i];
if (dynamic_cast<Hourly*>(empPtr))
{
...
}

Array of structs declaration

I am trying to write this C++ function in which I am trying to set each Sequence in the array of Sequences, however when I follow the code on debug I notice that the array is not changing. In particular:
compressed.data[compressedDataCounter].c = pic.data[i];
compressed.data[compressedDataCounter].times = counter+1;
don't seem to add any new variables to the array, just override the first one.
I am thinking that the root of the problem is the declaration:
CompressedPic compressed;
compressed.data = new Sequence[pic.height * pic.width];
This is the portion of the code:
struct Sequence
{
char c;
int times;
};
struct CompressedPic
{
int height;
int width;
Sequence* data;
};
struct Picture
{
int height;
int width;
char* data;
};
CompressedPic compressThePicture(Picture pic) {
CompressedPic compressed;
compressed.data = new Sequence[pic.height * pic.width];
compressed.height = pic.height;
compressed.width = pic.width;
int compressedDataCounter=0;
for(int i=0; i<(pic.height * pic.width)-1; i++)
{
int counter = 0;
while(pic.data[i] == pic.data[i+1])
{
i++;
counter++;
}
compressed.data[compressedDataCounter].c = pic.data[i];
compressed.data[compressedDataCounter].times = counter+1;
compressedDataCounter++;
}
compressed.data[compressedDataCounter].times = -1;
return compressed;
}
It would be great if someone could figure out why this is happening.
You might want to change:
compressed.data[compressedDataCounter].c = counter+1;
to:
compressed.data[compressedDataCounter].times = counter+1;
So you can change the .times member otherwise you will be overriding your .c member. Right now you are setting .c to 'a' for example. Then you set .c to 103 (counter+1). Which is an int and likely with your archetecture the high bytes are aligning with .c and setting it to 0 as well.
So .c is getting 0'd and .times is never set