简体   繁体   中英

C: incomplete definition of type 'struct date' error

i started learning C and just ran into an issue.

I created a date ADT and would like to test it out :)

basically, i would like to read in a string from standard input, convert it to the date and print it out on standard output.

after compiling these files i got the following errors:

datetest.c:15:45: error: incomplete definition of type 'struct date'
  printf("Year: %d Month: %d Day: %d", d->year, d->month, d->day);
                                       ~^
./date.h:4:16: note: forward declaration of 'struct date'
typedef struct date Date;

What am i doing wrong?

date.c:

#include "date.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct date {
  int day;
  int month;
  int year;
};

/*
 * date_create creates a Date structure from `datestr`
 * `datestr' is expected to be of the form "dd/mm/yyyy"
 * returns pointer to Date structure if successful,
 *         NULL if not (syntax error)
 */
Date *date_create(char *datestr) {
  Date *d = (Date *)malloc(sizeof(Date));
  const char delimiter[2] = "/";
  char *token;

  if (d != NULL) {  
    token = strtok(datestr, delimiter);
    d->day = atoi(token);
    token = strtok(NULL, delimiter);
    d->month = atoi(token);
    token = strtok(NULL, delimiter);
    d->year = atoi(token);
    //printf("Day: %d Month: %d Year: %d\n", d->day, d->month, d->year);    
    //printf("Day: %p Month: %p Year: %p\n", *d->day, *d->month, *d->year);
  }
  return d;
};

/*
 * date_duplicate creates a duplicate of `d'
 * returns pointer to new Date structure if successful,
 *         NULL if not (memory allocation failure)
 */
Date *date_duplicate(Date *d) {
  Date *dd = (Date *)malloc(sizeof(Date));
  if (dd != NULL) {
    dd->day = d->day;
    dd->month = d->month;
    dd->year = d->year;
  }
  return dd;
};

/*
 * date_compare compares two dates, returning <0, 0, >0 if
 * date1<date2, date1==date2, date1>date2, respectively
 */
int date_compare(Date *date1, Date *date2) {
  if (date1->year < date2->year)
    return -1;
  else if (date1->year > date2->year)
    return 1;
  else {
    if (date1->month < date2->month)
      return -1;
    else if (date1->month > date2->month)
      return 1;
    else {
      if (date1->day < date2->day)
    return -1;
      else if (date1->day > date2->day)
    return 1;
      else
    return 0;
    }
  }
};

/*
 * date_destroy returns any storage associated with `d' to the system
 */
void date_destroy(Date *d) {
  if (d != NULL)
    free(d);
};

datetest.c:

#include "date.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
  Date *d;
  char buf[1024], *s;

  while (fgets(buf, sizeof(buf), stdin) != NULL) {
    if (!(d = date_create(buf))) {
    fprintf(stderr, "Unable to create a date.\n");
    return -1;
    }
      printf("Year: %d Month: %d Day: %d", d->year, d->month, d->day);
  }
}

date.h:

#ifndef _DATE_H_INCLUDED_
#define _DATE_H_INCLUDED_

typedef struct date Date;

/*
 * date_create creates a Date structure from `datestr`
 * `datestr' is expected to be of the form "dd/mm/yyyy"
 * returns pointer to Date structure if successful,
 *         NULL if not (syntax error)
 */
Date *date_create(char *datestr);

/*
 * date_duplicate creates a duplicate of `d'
 * returns pointer to new Date structure if successful,
 *         NULL if not (memory allocation failure)
 */
Date *date_duplicate(Date *d);

/*
 * date_compare compares two dates, returning <0, 0, >0 if
 * date1<date2, date1==date2, date1>date2, respectively
 */
int date_compare(Date *date1, Date *date2);

/*
 * date_destroy returns any storage associated with `d' to the system
 */
void date_destroy(Date *d);

#endif /* _DATE_H_INCLUDED_ */

You're defining struct date in date.c, datetest.c has no idea what it is. Declare it in date.h instead. Currently it's an opaque type - anything that includes date.h can make a pointer to it, but can't access the members.

datetest.c:15:45: error: incomplete definition of type 'struct date'
  printf("Year: %d Month: %d Day: %d", d->year, d->month, d->day);
                                       ~^
./date.h:4:16: note: forward declaration of 'struct date'
typedef struct date Date;

When the compiler parses date.h , it detects that date.h doesnt have struct date but it uses date . So it throws that note note: forward declaration of 'struct date'

In datetest.c you have included date.h but not the actual definition which is in date.c and the compiler is not able to detect the type. Thats why it throws the error

error: incomplete definition of type 'struct date'

To fix this,

struct date {
  int day;
  int month;
  int year;
};

Move this to date.h file.

Your program declares the struct date in the .c file which means you only have access to the things declared in the .h file.

The reason you can declare the date is because you make it a pointer and the compiler knows the size of all pointers. However, it knows nothing about the members of a date and, consequently, you are unable to call members like d->year, d->month, d->day , etc. Calling these members gives you your error.

One alternative is to make some interface functions which return the year , month , etc.

Since you are probably in a data structures class, and the header file is provided for you and have been instructed not to alter it. I would just call functions in the header file ONLY, and print things like "passed" when they work as expected and show the program did not segmentation fault, and leave it at that without needing to call year , month , etc.

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