Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression must have pointer to struct or union error

Tags:

c

pointers

t variable is coming up with an error from assigntime function onwards saying it must have a pointer to a struct or union type. pointers are my weakness, if anyone could explain, not just give me the answer, what i need to do to fix this that would be most helpful! cheers.

//MY TIME C FILE
#include "my_time.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct my_time_int 
{
    int hour;
    int minute;
    int second;
};

void init_my_time(my_time *t)
{

    t=(my_time)malloc(sizeof(struct init_my_time*)); 
}

/*
 * Alter hour, minute, and second
 * Param h new value for hour
 * Param m new value for minute
 * Param s new value for second
*/
void assignTime(my_time *t, int h, int m, int s) 
{
    t->hour = h;
    t->minute = m;
    t->second = s;
}
//FOLLOWING CODE T VARIABLE HAS RED UNDERLINE ERROR SAYING EXPRESSION MUST HAVE POINTER TO STRUCT OR UNION>
char *toString(my_time t)
{ 
    char *r = (char *)malloc(12 * sizeof(char));

    if (t.hour >= 12) {
    if (t.hour == 12)
        sprintf(r, "%02d:%02d:%02d PM", 12, t.minute, t.second);
    else
        sprintf(r, "%02d:%02d:%02d PM", t.hour - 12, t.minute, t.second);
    }
    else {
        if (t.hour == 0)
        sprintf(r, "%02d:%02d:%02d AM", 12, t.minute, t.second);
        else
        sprintf(r, "%02d:%02d:%02d AM", t.hour, t.minute, t.second);
    }

    return r;

}

/*
 * Find printable form of time in 24 hour mode
 * Return String form of time in 24 hour mode for printing etc.
*/
char *toMilString(my_time t)
{ 
    char *s = (char *)malloc(9 * sizeof(char));

    sprintf(s, "%02d:%02d:%02d", t.hour, t.minute, t.second);
    return s;
}

/*
 * Find number of seconds elapsed since midnight
 * Return number of seconds elapsed since midnight as int
*/
int secsSinceMidnight(my_time t)
{
return t.second + (60 * t.minute) + (60 * 60 * t.hour);
}

Header File Here:

#include <stdbool.h>

struct my_time_int;
typedef struct my_time_int *my_time;

void init_my_time(my_time *t);
void assignTime(my_time *t, int h, int m, int s);
void addTime(my_time t, double s);
char *toString(my_time t);
char *toMilString(my_time t);
bool equals(my_time this, my_time that);
bool my_timeIncHour(my_time *t);
bool my_timeIncMinute(my_time *t);
bool my_timeIncSecond(my_time *t);
like image 782
Jonno Williams Avatar asked Sep 29 '22 04:09

Jonno Williams


1 Answers

There are a couple of errors in your code.

Primarily the use of pointers it's not correct in respect to the desired outcome. In the header you have the line:

typedef struct my_time_int *my_time;

which effectively declares my_timebeing a pointer type to the struct my_time_int. But in your function's prototypes (and definitions too) you use a pointer to my_time as argument: my_time* t. In fact here you are using a pointer to a pointer to the struct my_time_int.

So when you try to assign to tusing the deference arrow operator -> you make a mistake, because in fact you are assigning to a pointer to a pointer to a struct not to a plain pointer to a struct as you wish.

You should also avoid using the . operator on variables of type my_time because they are in facts pointers. You should use instead the arrow ->operator on them.

Here the proposed solution:

//MY TIME C FILE
#include "prova.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

struct my_time_int
{
    int hour;
    int minute;
    int second;
};

//void init_my_time(my_time *t)
my_time init_my_time()
{
    //t=(my_time)malloc(sizeof(struct init_my_time*));
    return (my_time)malloc(sizeof(struct my_time_int));
}

/*
 * Alter hour, minute, and second
 * Param h new value for hour
 * Param m new value for minute
 * Param s new value for second
*/
//void assignTime(my_time *t, int h, int m, int s) 
void assignTime(my_time t, int h, int m, int s)
{
    t->hour = h;
    t->minute = m;
    t->second = s;
} 

//FOLLOWING CODE T VARIABLE HAS RED UNDERLINE ERROR SAYING EXPRESSION MUST             HAVE POINTER TO STRUCT OR UNION>
char *toString(my_time t)
{ 
char *r = (char *)malloc(12 * sizeof(char));

//if (t.hour >= 12) {
if(t->hour >= 12){
//if (t.hour == 12)
if(t->hour == 12)
    //sprintf(r, "%02d:%02d:%02d PM", 12, t.minute, t.second);
    sprintf(r, "%02d:%02d:%02d PM", 12, t->minute, t->second);
else
    //sprintf(r, "%02d:%02d:%02d PM", t.hour - 12, t.minute, t.second);
    sprintf(r, "%02d:%02d:%02d PM", t->hour - 12, t->minute, t->second);
}
else {
    //if (t.hour == 0)
    if (t->hour == 0)
    //sprintf(r, "%02d:%02d:%02d AM", 12, t.minute, t.second);
    sprintf(r, "%02d:%02d:%02d AM", 12, t->minute, t->second);
    else
    //sprintf(r, "%02d:%02d:%02d AM", t.hour, t.minute, t.second);
    sprintf(r, "%02d:%02d:%02d AM", t->hour, t->minute, t->second);
}

return r;

}

/*
 * Find printable form of time in 24 hour mode
 * Return String form of time in 24 hour mode for printing etc.
*/
char *toMilString(my_time t)
{ 
    char *s = (char *)malloc(9 * sizeof(char));

    //sprintf(s, "%02d:%02d:%02d", t.hour, t.minute, t.second);    
    sprintf(s, "%02d:%02d:%02d", t->hour, t->minute, t->second);
    return s;
}

/*
 * Find number of seconds elapsed since midnight
 * Return number of seconds elapsed since midnight as int
*/
int secsSinceMidnight(my_time t)
{
//return t.second + (60 * t.minute) + (60 * 60 * t.hour);
return t->second + (60 * t->minute) + (60 * 60 * t->hour);
}

And header too:

#include <stdbool.h>

struct my_time_int;
typedef struct my_time_int *my_time;

//void init_my_time(my_time *t);
my_time init_my_time();
//void assignTime(my_time *t, int h, int m, int s);
void assignTime(my_time t, int h, int m, int s);

//and son on removing the unnecessary pointer types
void addTime(my_time t, double s);
char *toString(my_time t);
char *toMilString(my_time t);
bool equals(my_time this, my_time that);
bool my_timeIncHour(my_time t);
bool my_timeIncMinute(my_time t);
bool my_timeIncSecond(my_time t);

As you can se in the commented code there are the previous erroneous declarations and definitions.

EDIT

As pointed in the comments, the init_my_time, as defined, leaks memory because allocates a pointer that it doesn't return to the caller. The right thing to do here is to allocate the memory and return the pointer to that memory to the caller. This requires changing the declaration and definition of init_my_time as already done above in the code.

like image 85
Giova Avatar answered Oct 12 '22 23:10

Giova