简体   繁体   中英

changing values of struct tm in function

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM