0

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 Struct array idea

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:
struct

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

6
  • another way that i could it is struct file { char Filenr; int grocery1; int grocery2; int grocery3; int quantity1; int quantity2; int quantity3; float unitprice1; float unitprice2; float unitprice3; }; struct file tabel[5]; I just feel like it's a more messy way to do it Commented Oct 25, 2020 at 21:11
  • The term "struct array" doesn't make sense. You want an array of structs. Are you sure you will need 3 grocery, 3 quantity, and 3 unit price? And moreover why is this a file? Commented Oct 25, 2020 at 21:17
  • what does Filenr represent? Commented Oct 25, 2020 at 21:17
  • 3
    And please remove that image, putting your code as a code block. Commented Oct 25, 2020 at 21:18
  • 1
    The drawing does NOT represent an array of struct file. Adding arrays with struct file would be counter-productive. You would lose the coordination among grocery, quantity and unitprice. An array of struct file would preserve that coordination. (which is why you use a struct to begin with...) Commented Oct 25, 2020 at 21:23

2 Answers 2

0

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

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you so much this helps me out a lot. My computer just died and I’m in the train so I can’t make sure it works. But from just looking it over it looks exactly like what I was looking for
Keep in mind however, this might be overkill for what you actually need. It might be a better structure, to combine the items into 1 struct, and just doing a single "malloc"
Also... I just assumed you were coding in C. If you are programming in C++, you should not follow this example, and use "new / delete" to dynamically allocate memory
I’ll take a look and if it overkill I’ll simplify it a bit so it works. And yes I do code in C
@IlanKeshet There is almost never a good reason to use the new or delete expressions in modern C++, except when an older interface demands it.
0

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, e.g.

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.