0

For a c programming class, I have been told to create the following structs with typedefs, in that order:

//STRUCTS
struct time {
    unsigned int hour;
    unsigned int minute;
    unsigned int second;
};//end struct time
struct date {
    unsigned int month;
    unsigned int day;
    unsigned int year;
};//end struct Date
struct event {
    char name[20];
    struct time* time;
    struct date* date;
};//end struct event

//TYPEDEFS
typedef struct time Time;
typedef struct date Date;
typedef struct event Event;

From there I'm supposed to ask for the max number of events to create, then allocate a pointer with enough memory for that many Events. Part of my work is:

Event *events;

//Ask for max number of events and allocate memory
printf("Number of events to add: ");
scanf("%d", &numEvents);
events = (Event*) malloc(sizeof(Event) * numEvents);

However, from there I'm unsure of what to do to traverse the pointer to view a specific event. I know it isn't just an array, so events[i] won't work. but beyond that, I'm lost. My (broken)function for getting an event is:

void getEvent(Event *events, int index){
    //variables
    char title[20];
    unsigned int day, month, year, hour, minute, second;
    Event tempEvent;


    //Ask for input
    printf("Input title, date, and time.\n");
    if(index == 0)
        printf("example -> title: dd/mm/yy hh:mm:ss\n");

    //Take input
    scanf("%20[^:]: %u/%u/%u %u:%u:%u", title, &day, &month, &year, &hour, &minute, &second);


    tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } };

    events[index] = tempEvent;      
}

I know that it isn't right, and I got a segmentation fault on testing.

When I compile, I get these warnings (and some repeats about similar things):

Lab4.c: In function ‘getEvent’: Lab4.c:82:2: warning: braces around scalar initializer 
tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } }; 
^ Lab4.c:82:2: note: (near initialization for ‘(anonymous).name[1]’)

Lab4.c:82:39: warning: excess elements in scalar initializer 
tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } }
user3386109
  • 34,287
  • 7
  • 49
  • 68
Cutler Cox
  • 33
  • 1
  • 5
  • 6
    events[i] will totally work. In C, array notation is shorthand for pointer arithmetic, so events[i] is equivalent to *(events+i) – Jeremy Friesner Oct 13 '16 at 02:03
  • 1
    Also, [don't cast the return value of malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Robert Prévost Oct 13 '16 at 02:04
  • What warnings are you getting from the compiler? – user3386109 Oct 13 '16 at 02:12
  • @JeremyFriesner How do I access the fields of the results? Will `events[i]->time->hour` work correctly? – Cutler Cox Oct 13 '16 at 02:12
  • @user3386109 `Segmentation fault (core dumped)` Though I was trying to access the items and print them. That may have done it – Cutler Cox Oct 13 '16 at 02:13
  • Really, these are basic C syntax questions. Does your class not provide teaching material or recommend a text book? Those are more productive sources for you to learn basic C syntax rather than posting here. – kaylum Oct 13 '16 at 02:14
  • @13islucky No, that's the error that you get when you run the program. I'm asking what warnings you got when you compiled the program. Two things you need to know about compiling C programs. First, always compile with all warnings enabled (`-Wall` for gcc,clang `/W4` for microsoft). Second, don't even bother trying to run the program until you've fixed ***all*** of the warnings. – user3386109 Oct 13 '16 at 02:17
  • @user3386109 `Lab4.c: In function ‘getEvent’: Lab4.c:82:2: warning: braces around scalar initializer tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } }; ^ Lab4.c:82:2: note: (near initialization for ‘(anonymous).name[1]’) Lab4.c:82:39: warning: excess elements in scalar initializer tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } }` And a few more repeats of similar things, just pointing at different elements in the above – Cutler Cox Oct 13 '16 at 02:28
  • In real code you would use `struct time time;`, not `struct time* time;` . Does the class force you to use the latter? – M.M Oct 13 '16 at 04:05

1 Answers1

2

The compiler is telling you that line 82 is a mess.

tempEvent = (Event) {*title, { hour, minute, second }, { month, day, year } };

In particular, the first member of the event structure is an array char name[20], but you attempt to initialize it with a single character *title. But the bigger problem is that time and date (in the event structure) are pointers, and you haven't allocated any memory for those pointers.

One solution is to allocate memory, and then have scanf fill in the values, like this:

void getEvent( Event *events, int n )
{
    // allocate memory
    events[n].time = malloc(sizeof(Time));
    events[n].date = malloc(sizeof(Date));
    if ( events[n].time == NULL || events[n].date == NULL )
    {   /* TODO: handle the error */ }

    //Ask for input
    printf("Input title, date, and time.\n");
    if ( n == 0 )
        printf("example -> title: dd/mm/yy hh:mm:ss\n");

    //Take input
    int count = scanf( "%20[^:]:%u/%u/%u%u:%u:%u", events[n].name,
                       &events[n].date->day, &events[n].date->month, &events[n].date->year,
                       &events[n].time->hour, &events[n].time->minute, &events[n].time->second );
    if ( count != 7 )
    {   /* TODO: handle the error */ }
}
user3386109
  • 34,287
  • 7
  • 49
  • 68
  • I see you have the todo: handle errors, but what exactly do you aim to do with these ifs? – Cutler Cox Oct 13 '16 at 06:02
  • 1
    @13islucky I leave that for you to do. You have to decide what the program should do if there's no memory left (the first TODO). And you need to decide what the program should do if the user input is not valid (the second TODO). – user3386109 Oct 13 '16 at 06:18