在函数中改变struct tm的值

时间:2014-08-29 09:13:59

标签: c struct

我正在开发一个功能,该功能应该提示用户输入任意时间和日期。 我希望将这些值存储在struct tm中,但它无法正常工作:

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;
}

我正在使用这样的功能:

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;
}

令我惊讶的是,我可能会使用像

这样的东西
TIME->tm_year=12;

在main()中工作,但不在我的函数中。那么区别在哪里,struct tm和其他结构之间有什么区别?

1 个答案:

答案 0 :(得分:0)

当编译器说TIME未初始化时,它是正确的。你的指针TIME没有指向任何有意义的地方,访问它可能会使程序崩溃。

从您的评论中我发现您还不熟悉指针。在这种情况下,您可以直接使用struct tm。这样您就不必担心内存管理,因为struct是按值传递的。

如果要使用指针,则必须使指针指向有效内存。获得此功能的一种方法是使用malloccalloc在堆上分配内存。然后可以从您的函数外部访问该内存,但是当您不再需要它时,您应该free

下面的示例程序使用两种方法:xmas适用于指针,newyear适用于普通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;
}

在掌握指针(包括堆上的内存分配以外)之前,使用普通结构可能会更容易。