Array of Structs with String

Hi,

I am trying to declare following Struct:

typedef struct
{

  char* SKU[];
  char* ProductName[];
  char* Description[];
  float MRP;
  float OfferPrice;
 
} ProductData;

ProductData Product[2]{
  
  {"AH00007","Blend Micro","Blend Micro is a RedBearLab Arduino at Heart integrated development board, they have \"blend\"ed Arduino with Bluetooth 4.0 Low Energy (aka BLE or Bluetooth Smart) into a single board. It is targeted for makers to develop low power Internet-Of-Things (IoT) projects quickly and easily.",20,15},
  {"GBX00004","Genuino MKR1000","Genuino MKR1000 has been designed to offer a practical and cost effective solution for makers seeking to add WiFi connectivity to their projects with minimal previous experience in networking. The design includes a Li-Po charging circuit that allows the Genuino MKR1000 to run on battery power or external 5V, charging the Li-Po battery while running on external power. Switching from one source to the other is done automatically.",30.99,20.99}
  
  
  };

But I am getting errors while compilation:

Struct:22: error: too many initializers for 'ProductData'
   };
   ^
Struct:22: error: too many initializers for 'ProductData'
Struct:22: error: cannot convert 'const char*' to 'float' in initialization
Struct:22: error: cannot convert 'const char*' to 'float' in initialization
Struct:22: error: cannot convert 'const char*' to 'float' in initialization
Struct:22: error: cannot convert 'const char*' to 'float' in initialization
exit status 1
too many initializers for 'ProductData'
typedef struct
{

  char* SKU;
  char* ProductName;
  char* Description;
  float MRP;
  float OfferPrice;
 
} ProductData;

Remove the square brackets in the struct

typedef struct
{

  char* SKU[];
  char* ProductName[];
  char* Description[];
  float MRP;
  float OfferPrice;
 
} ProductData;

E.g. char* SKU[] declares an array of pointers, not a pointer (to an array). char* SKU declare a pointer (to e.g. an array).

Got it. Thank you @Coding Badly and @sterretje. I was able to compile now.

I have another doubt:

If I am using ProductData Product[50] {

{},
...{50th data}

};

How to get the size of how many such data are store in the array of Struct. I am trying to use sizeof(Product) but I think I am getting total byte value, I need to get the array value.

I suspect this is what you want…

typedef struct
{
  char* SKU;
  char* ProductName;
  char* Description;
  float MRP;
  float OfferPrice;
} 
ProductData;

ProductData Products[] = 
  {
    {"AH00007","Blend Micro","Blend Micro is a RedBearLab Arduino at Heart integrated development board, they have \"blend\"ed Arduino with Bluetooth 4.0 Low Energy (aka BLE or Bluetooth Smart) into a single board. It is targeted for makers to develop low power Internet-Of-Things (IoT) projects quickly and easily.",20,15},
    {"GBX00004","Genuino MKR1000","Genuino MKR1000 has been designed to offer a practical and cost effective solution for makers seeking to add WiFi connectivity to their projects with minimal previous experience in networking. The design includes a Li-Po charging circuit that allows the Genuino MKR1000 to run on battery power or external 5V, charging the Li-Po battery while running on external power. Switching from one source to the other is done automatically.",30.99,20.99}
  };

const size_t NumberOfProducts = sizeof(Products) / sizeof(Products[0]);

void setup( void ) 
{ 
  Serial.begin( 250000 );

  for ( unsigned i=0; i < NumberOfProducts; ++i )
  {
    Serial.print( Products[i].SKU );
    Serial.write( '\t' );
    Serial.print( Products[i].ProductName );
    Serial.println();
  }
}

void loop( void ) { }
Serial.println(sizeof(Product) / sizeof(ProductData));

sizeof operator

@Coding Badly
Without wanting to derail the thread, what happens if one declares an empty array (not very useful but possibly while playing / testing) and one uses your approach?

ProductData Products[] =
{
};

Tested it and it does not (seem) to crash. Why does it return 14 (which is indeed the size) if there is no Product[0]?

sizeof does not require storage. It only requires datatype. The datatype of Products[0] is the same as the datatype of Products[1478552] which is the same as the datatype of ProductData. Obviously, the second cannot possibly have storage on an AVR processor. But, the compiler does not care. It is only interested in datatype.

This defines both storage and datatype for (notice the absence of brackets) Products...

ProductData Products[] =
  {
    {"AH00007","Blend Micro","Blend Micro is a RedBearLab Arduino at Heart integrated development board, they have \"blend\"ed Arduino with Bluetooth 4.0 Low Energy (aka BLE or Bluetooth Smart) into a single board. It is targeted for makers to develop low power Internet-Of-Things (IoT) projects quickly and easily.",20,15},
    {"GBX00004","Genuino MKR1000","Genuino MKR1000 has been designed to offer a practical and cost effective solution for makers seeking to add WiFi connectivity to their projects with minimal previous experience in networking. The design includes a Li-Po charging circuit that allows the Genuino MKR1000 to run on battery power or external 5V, charging the Li-Po battery while running on external power. Switching from one source to the other is done automatically.",30.99,20.99}
  };

The compiler knows that Products is an array of ProductData and it knows that there are two elements in the array. The exact datatype for Products is an array with two elements of ProductData structures. Knowing the exact datatype allows the compiler to determine the size of Products.

Which means this...

extern ProductData OtherProducts[];
...
  Serial.println( sizeof(OtherProducts) );

...will not compile because the compiler has no way of knowing how many elements are in OtherProducts.

However, this...

extern ProductData OtherProducts[];
...
  Serial.println( sizeof(OtherProducts[0]) );

...will compile because OtherProducts[0] is the exact same datatype as ProductData and the compiler does know the size of that datatype.

sterretje:
Why does it return 14 (which is indeed the size) if there is no Product[0]?

I assume the C++ standard calls for a single zero initialized array element for your example. Both storage and datatype are defined.

Make sense?

Yes. I have understood now. Thanks very much.

gauman1981, I promise you that you will come to regret using floats for prices. I have been there.

A floating point value is almost never accurate - it should always be treated as an approximation. It's ok for things like physical quantities or statistical artifacts. Never use them for things that need to be exact. Most particularly, there is no exact floating-point representation for .99 . You just get the number which is as close as possible to .99 . Not the same thing.

Hold your prices in cents. Calculate them with integer-valued variables. Trust me on this: I have been making a living programmiung for a long time.

PaulMurrayCbr, Noted! Thanks very much for the tip.

While it may never be a problem, keep in mind that tracking cents with a signed integer maxes out at $327.67. Using an unsigned int about doubles that value. If you're buying/selling things that overflow an unsigned long, you and I need to be friends.