I'm working on a function which should prompt the user to enter an arbitrary time and date. These values I want to store in struct tm, but it doesn't work properly:
struct tm * enter_time_GMT(){
struct tm *TIME;
char input[50];
int check=0, buffer;
printf("date:\n");
do{
printf("day > ");
scanf("%49s",&input[0]);
buffer=atoi(input);
if(buffer>=1 && buffer<=31){
check=1;
/* program crashes here, compiler says TIME uninitialized: */
TIME->tm_mday=buffer;
}
else{
check=0;
printf("wrong input\n");
}
}while(check==0);
/* just a short part of the full function */
return TIME;
}
I'm using the function like this:
int main(){
struct tm *sysTIME; /* why does the compiler want me to use tm* instead of tm? */
char buffer[80];
sysTIME=enter_time_GMT();
strftime(buffer, 80, "%d.%m.%Y %H:%M:%S", sysTIME);
printf("%s\n", buffer);
return 0;
}
To my surprise I may use things like
TIME->tm_year=12;
work in main(), but not in my function. So where is the difference, and what is the difference between struct tm and other structs?
When your compiler says that TIME
isn't initialised, it is correct. Your pointer TIME
doesn't point anywhere meaningful and accessing it will likely crash the program.
From your comments I see that you are not yet familiar with pointers. In that case, you can use a struct tm
directly. That way you don't have to worry about memory management, because struct
s are passed by value.
If you want to use pointers, you must make the pointer either point to valid memory. One way to get that is to allocate memory on the heap with malloc
or calloc
. That memory will then be accessible from outside your function, but you should free
it later, when you don't longer need it.
The example program below uses both methods: xmas
works with pointers and newyear
works with a plain struct tm
:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
struct tm *xmas(int year)
{
struct tm *t = calloc(1, sizeof(*t)); // must be free'd after use
t->tm_mday = 24;
t->tm_mon = 11;
t->tm_year = year - 1900;
return t; // pointers to memory on the heap can be safely returned
}
struct tm newyear(int year)
{
struct tm t = {0};
t.tm_mday = 1;
t.tm_mon = 0;
t.tm_year = year - 1900;
return t; // structure is returned "by value"
}
int main()
{
struct tm *x = xmas(2014);
struct tm ny = newyear(2015);
char buf[30];
strftime(buf, sizeof(buf), "%D", x);
puts(buf);
strftime(buf, sizeof(buf), "%D", &ny);
puts(buf);
// Free ressources of allocated memory
free(x);
return 0;
}
Using plain structures is probably easier until you have a firm grasp of pointers (which includes more than allocation of memory on the heap).
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.