1

I need to store multiple distinguishable members in a struct for a personal diary to show different records for each day. I want multiple members like e1 without writing it 365 times. I want a solution that works e1 on a loop or on an array.

struct add
{
   char day[365];
   char date[365];
   char time[365];
   char place[365];
   char data[365]; 
};

int main()
{
   int i=1;
   struct add e1;
   while(i!=0)
   {
        printf("Enter Day:");
        gets(e1.day);
        printf("Enter Date:");
        gets(e1.date);
        printf("Enter Time:");
        gets(e1.time);
        printf("Enter Place:");
        gets(e1.place);
        printf("Tell me about your day:");
        gets(e1.data);
        printf("\n\n\n");
        printf("Day: %s\n",e1.day);
        printf("Day: %s\n",e1.date);
        printf("Day: %s\n",e1.time);
        printf("Day: %s\n",e1.place);
        printf("Day: %s\n\n\n",e1.data);
    }
    return 0;
}
Anton Menshov
  • 2,266
  • 14
  • 34
  • 55
RustyGAWWD
  • 11
  • 2
  • Please use a more orthodox indentation style for C. I strongly recommend either Allman (which is what I use, more or less) or some version of 1TBS (which is used by many other people). See Wikipedia on [Indentation Style](https://en.wikipedia.org/wiki/Indentation_style) for information about the variants. The Pico style, especially with multiple `}` markers on a single line, is anathema in C. Multiple close braces on a single line is a no-no; multiple consecutive close braces at the same indent level is another. – Jonathan Leffler Aug 28 '21 at 06:05
  • 2
    Note that [it is impossible to use the `gets()` function safely](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) and it is no longer a part of standard C. Do not use it — ever! – Jonathan Leffler Aug 28 '21 at 06:10
  • I did use a proper indentation. I think it glitched. – RustyGAWWD Aug 28 '21 at 06:10
  • 1
    What is the problem with `struct add e[365];` and then referencing `e[i].day` etc in your loop? The loop control would be rewritten `for (i = 0; i < 365; i++)`. Note that your `while` loop never changes `i`, so it runs indefinitely. – Jonathan Leffler Aug 28 '21 at 06:13
  • Are you expecting your structure to hold 365 strings for `day`, or are you intending to allow the description of a `day` to be up to 364 characters plus a null byte? The second is what you get. An alternative structure would use far shorter strings for the elements, and then you'd use an array of that revised structure type, as I suggested in my previous comment. – Jonathan Leffler Aug 28 '21 at 06:26

3 Answers3

0

I don't think its possible to create different variable with each loop, you can refer to this question for info. Instead of making different instances, make your struct in a way so that it stores data for all (365) days. Something like array of strings so that it stores for all days, currently even if you write something like char day[365] it creates separate day for each instance. make something like:

struct add
{
   char day[NUMBER_OF_STRING][MAX_STRING_SIZE]; // syntax

   // MAX_STRING_SIZE does not need to be 365, i just used it because you used that
   // otherwise it does not make sense, date , time etc won't take more than 10 char
   
   char date[365][365];
   char time[365][365];
   char place[365][365];
   char data[365][365]; 
};

Now keep on adding to a single instance of struct add using for loop, this should be easy.

Also Better approach can be to create a array of struct add itself with your original struct code.

Suryansh Singh
  • 1,123
  • 7
  • 15
  • There would need to be a very good reason to have the arrays inside the structure as shown, rather than using an array of structures more like the one shown in the question. I agree that the field sizes in the original are dubious. – Jonathan Leffler Aug 28 '21 at 06:30
  • @JonathanLeffler I don't know for sure, but people create vector inside classes that's why I tried doing something similar. – Suryansh Singh Aug 28 '21 at 06:35
0

This example does what you want, and you can create as many instance of add as you want.

I limit your loop to run once and have tested that the code works with visual studio 2019:

#include <stdio.h>
#include <string.h>
#include <malloc.h>

#define DAY_SIZ 20
#define DATE_SIZ 40
#define TIME_SIZ 20
#define PLACE_SIZ 120
#define DATA_SIZ (BUFSIZ - 1)

struct add
{
    char day[DAY_SIZ];
    char date[DATE_SIZ];
    char time[TIME_SIZ];
    char place[PLACE_SIZ];
    char data[DATA_SIZ];
};

struct add* create_add_struct() {
    struct add* rec;
    rec = (struct add*)malloc(sizeof(struct add));
    return rec;
}

void destroy_add_struct(struct add* rec) {
    free(rec);
}

void clear_add_struct(struct add* rec) {
    memset(rec->day, 0, sizeof(rec->day));
    memset(rec->date, 0, sizeof(rec->date));
    memset(rec->time, 0, sizeof(rec->time));
    memset(rec->place, 0, sizeof(rec->place));
    memset(rec->data, 0, sizeof(rec->data));
}

void get_text_from_user(const char prompt[], char *txt, int siz) {
    char buf[BUFSIZ];
    printf("%s", prompt);
    fgets(buf, BUFSIZ, stdin);
    memcpy(txt, buf, siz);
}

void fill_add_struct(struct add* rec) {
    printf("Do not enter any lines longer than %d\n\n", BUFSIZ);
    get_text_from_user("Enter Day:", rec->day, sizeof(rec->day) - 1);
    get_text_from_user("Enter Date:", rec->date, sizeof(rec->date) - 1);
    get_text_from_user("Enter Time:", rec->time, sizeof(rec->time) - 1);
    get_text_from_user("Enter Place:", rec->place, sizeof(rec->place) - 1);
    get_text_from_user("Tell me about your day:", rec->data, sizeof(rec->data) - 1);
}

void print_add_struct(struct add* rec) {
    printf("\n\n\n");
    printf("Day  : %s\n", rec->day);
    printf("Date : %s\n", rec->date);
    printf("Time : %s\n", rec->time);
    printf("Place: %s\n", rec->place);
    printf("Data : %s\n\n\n", rec->data);
}

int main()
{
    // The number of times we want the loop to run
    int i = 1;
    // Collect data from the user and print it
    while (i-- != 0)
    {
        // Allocate memory and initialize it
        struct add* rec = create_add_struct();
        clear_add_struct(rec);
        // Get data from the user and print it
        fill_add_struct(rec);
        print_add_struct(rec);
        // Release memory
        destroy_add_struct(rec);
    }
    // Return success
    return 0;
}

The reason I allocate your structure, is to make sure a stack-overflow does not occur, no pun intended.

If you want to create 365 add structs, you can create them like so:

struct add **records;
records = (struct add **) malloc(sizeof(struct add *) * 365);
for(int idx = 0; idx < 365; ++idx) {
    records[idx] = create_add_struct();
    clear_add_struct(records[idx]);
    /* ... insert code ... */
}
/* ... insert code ... */

// Free memory
for(int idx = 0; idx < 365; ++idx) {
    destroy_add_struct(records[idx]);
}
free(records);

I have not tested if the last piece of code compiles and works. Again I use malloc() and free() to avoid a stack-overflow.

GoWiser
  • 857
  • 6
  • 20
0
typedef struct
{
    time_t tm;
    char *description;
}entry;

typedef struct day
{
    time_t date;
    size_t nentries;
    struct day *next;
    entry entries[];
}day;

and create linked list od days. Every day has array of diary entries.

0___________
  • 60,014
  • 4
  • 34
  • 74