简体   繁体   中英

Struct array with array inside it

I have an assignment in my class where I would like to keep my variables in a struct array because I think it would be the most clean way to do it.

I drew up this quick drawing in paint just to make it easier to explain结构数组思想

This is just one of the "nodes" in the struct I would like to make the struct so I can duplicate everything after file in the drawing

not entirely sure how I go about doing this

so far I got a struct array that works fine. But I can't seem to figure out how to get the last row added, and by last row I mean Grocery 1-3, quantity 1-3 and unitprice 1-3.

for my struct I made:
结构

and that part works fine, but still missing the last "node"

Below is short example of creating an array of structs inside of a struct in C. I made it a an array of structs in side of a struct, because I thought you might want to customize what each of "Grocery" / "Price" / "UnitPrice" are.

In the code below, I used "malloc" to dynamically allocate an array of structs. This is the "C" style way to dynamically allocate memory. If you are using C++, then you should use "new"

I only assign the first item in the array with [0]. You could assign the others using [1], and [2] indices, respectively.

struct Grocery
{
   /* fill in details of Grocery here you could add more than 1 item*/
   int Value;
}

struct Quantity
{
   /* fill in details of Quantity here */
   int Value;
}

struct Unitprice
{
   /* fill in details of Unitprice here */
   int Value;
}

struct file
{
   struct Grocery* groceries;
   int totalGroceries;
   
   struct Quantity* quantities;
   int totalQuantities;
   
   struct Unitprice* unitprices;
   int totalUnitprices;
}

int main()
{
   struct file Table;
   
   Table.totalGroceries = 3
   Table.groceries = (struct Grocery*)malloc(Table.totalGroceries * sizeof(Grocery));
   
   Table.totalQuantities = 3
   Table.quantities = (struct Quantity*)malloc(Table.totalQuantities * sizeof(Quantity));
   
   Table.totalUnitprices = 3
   Table.unitprices = (struct Unitprice*)malloc(Table.totalUnitprices * sizeof(Unitprice));
   
   /* Assign details to groceries here */
   Table.groceries[0].Value = 5;
   
   /* Assign details to Quantity here */
   Table.quantities[0].Value = 5;
   
   /* Assign details to unitprices here */
   Table.unitprices[0].Value = 5;
   
   /* Other logic here */
   
   /* End of program deallocate allocated memory */ 
   free(Table.groceries);
   free(Table.quantities);
   free(Table.unitprices);
}

For more information I recommend you look at this link https://stackoverflow.com/questions/260915/how-can-i-create-a-dynamically-sized-array-of-structs#:~:text=If%20you%20want%20to%20allocate,type%20void%20(%20void*%20) on how to dynamically allocate array of structs in C

While your drawing and your description are in conflict to a certain extent, it appears you want to be able store data for a number of Items or Files where each item coordinates a grocery value, a quantity value and a unitprice values (similar to what you would use for the basis of an inventory system).

From your drawing, your Filenr struct member doesn't make much sense. Why? If your base Item struct coordinates grocery , quantity , and unitprice , then unless the Filenr provides an additional unique bit of information that is part of that grocery , quantity , and unitprice , then it can simply be omitted and you can use its index to describe the grocery , quantity , and unitprice .

Further, being of type char , its value would be limited to one of 256 values ( -128 - 127 ). If you are actually considering that to be a printable characters, then your range of values is reduced to just 96 printable characters.

You define your struct based on the data you have. If Filenr is a piece of data that is part of your input and is associated with grocery , quantity , and unitprice , then add it to your struct as a member. If it is just something you are using to refer to a unique struct, then it isn't needed -- UNLESS -- you can have two struct with the exact same values in grocery , quantity , and unitprice and you are using Filenr to disambiguate between two otherwise identical struct. Otherwise, omit it and use an index.

Without it, you would simply create an array of your structs. That would allow you to be able to sort, query and sum by any of the member values. A trivial implementation that prints the stored (made-up) values would be:

#include <stdio.h>

typedef struct {                /* your struct using a typedef for convenience */
    int grocery, quantity;
    double unitprice;
} item;

/* simple function to output all n struct in any array of item */
void prn_items (item *items, size_t n)
{
    for (size_t i = 0; i < n; i++)
        printf ("\nFilenr[%2zu]:\n grocery   : %d\n quantity  : %d\n unitprice : %0.4f\n",
                i, items[i].grocery, items[i].quantity, items[i].unitprice);
}

int main (void) {
    
    item files[] = {{ 31756, 22, 1.3405 },      /* made-up example data for array */
                    {  7818, 83, 2.4722 },
                    { 17920, 63, 1.3795 },
                    {  2937, 32, 2.8648 },
                    {  8423, 44, 2.6031 }};
    size_t n = sizeof files / sizeof *files;    /* number of elements in array */
    
    prn_items (files, n);                       /* output all struct */
}

Example Use/Output

Running the program simply outputs all stored struct values coordinated by index as the Filenr :

$ ./bin/grocerystruct

Filenr[ 0]:
 grocery   : 31756
 quantity  : 22
 unitprice : 1.3405

Filenr[ 1]:
 grocery   : 7818
 quantity  : 83
 unitprice : 2.4722

Filenr[ 2]:
 grocery   : 17920
 quantity  : 63
 unitprice : 1.3795

Filenr[ 3]:
 grocery   : 2937
 quantity  : 32
 unitprice : 2.8648

Filenr[ 4]:
 grocery   : 8423
 quantity  : 44
 unitprice : 2.6031

Now if your intent was to save each of the struct in a separate file, you could simply create an output filename with sprintf() that contains a unique suffix (or prefix) based on the index.

If you really want a single char and Filenr as part of your struct, you can simply include it by adding it back as a member, eg

typedef struct {                /* your struct using a typedef for convenience */
    char Filenr;
    int grocery, quantity;
    double unitprice;
} item;

Adjust the reminder of the code to handle the additional member.

Lastly, you don't want to use a floating-point number related to price. (companies get mad when you lose money due to rounding error). Better to use an integer value multiplied accordingly to ensure rounding error doesn't occur. You can search "floating point type for money" and find a wealth of additional information on that topic.

Look things over and let me know if you have further questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM