0

所以手头的问题是将格式为 YYYYMMDD 的数字字符串转换为其他结构中的 struct tm 类型成员。事实是,我真的只关心获得一个具有合理值的 struct tm 。

考虑以下结构:

typedef struct some_node {
    char somestring[64];
    char anotherstring[128];
    struct tm date_one;
    struct tm date_two;
    int some_val;
    struct some_node *prev;
    struct some_node *next;
} some_node_t;

在里面,我有两个来自 time.h 标头的 struct tm 类型的成员。看起来非常合理。那里还有指针成员可以创建一个链表,但这不是问题。

因此,我在尚未创建的链表中创建了第一个节点,如下所示:

/* begin the linked list of some_node_t */
struct some_node *t_head =
                calloc( (size_t) 1, sizeof( some_node_t ) );
if ( t_head == NULL ) {
    /*Memory allocation fault */
    printf ( " FAIL : Memory allocation fault at %s(%d)\n",
               __FILE__, __LINE__  );
    exit ( EXIT_FAILURE );
}

/* I used calloc above which zero fills memory so these 
 * next lines are not really needed. Better safe than sorry. */
t_head->some_val = 0;
t_head->prev = NULL;
t_head->next = NULL;

然后我可以将 char 数据填充到两个 char 成员中:

strcpy ( t_head->somestring, "birthday" );
strcpy ( t_head->anotherstring, "19981127" );

那里没问题。

在函数中将字符串转换为 struct tm 似乎是合理的,因为我可能必须这样做两次。

因此我写这个:

int timestr_to_tm ( struct tm **date_val, char *yyyymmdd ) {
    /* assume 8 digits received in format YYYYMMDD */
    int j, date_status = -1;
    char yyyy[5]="0000";
    char mm[3]="00";
    char dd[3]="00";

    /* copy over the year digits first */
    for ( j=0; j<4; j++ )
        yyyy[j]=yyyymmdd[j];

    /* month digits */
    mm[0]=yyyymmdd[4];
    mm[1]=yyyymmdd[5];

    /* day digits */
    dd[0]=yyyymmdd[6];
    dd[1]=yyyymmdd[7];

    *(date_val)->tm_year = atoi(yyyy) - 1900;
    *(date_val)->tm_mon = atoi(mm) - 1;
    *(date_val)->tm_mday = atoi(dd);
    *(date_val)->tm_hour = 0;
    *(date_val)->tm_min = 0;
    *(date_val)->tm_sec = 0;
    *(date_val)->tm_isdst = -1;

    return 0;

}

所以我的希望是我可以将指向 t_node 中成员 date_one 的指针传递给该函数。

if ( timestr_to_tm ( &(t_node->date_one), "19981127" ) < 0 ) {
    /* deal with a bad date conversion */
}

好吧,我的编译器在这里很合适。声称:

error: argument #1 is incompatible with prototype:

也许我应该有 &t_head->date_one 但我认为指针取消引用运算符“->”优先于“地址”运算符。甚至尝试将指针传递给结构中的成员可能是不好的策略?

更糟糕的是,在函数 timestr_to_tm() 内,我得到:

error: left operand of "->" must be pointer to struct/union

在我尝试将值分配给 struct tm 变量的那些行中。

我在没有传递指针的情况下尝试了所有这些,并且该过程有效,但是在返回时 struct tm 成员中没有任何内容。所以我想知道,我在这里缺少什么?

4

3 回答 3

2

如果你真的想传递一个指向 struct tm 的指针,你可以,你只需要创建一个指针变量来保存指针并将指针传递给它:

struct tm *pointer = &t_node->date_one;
if ( timestr_to_tm ( &pointer, "19981127" ) < 0 ) {
    ...

问题是为什么?您不需要额外的间接级别,因为您不想更改指针,您只想填写节点内的 struct tm 。所以只需使用一个指针:

int timestr_to_tm ( struct tm *date_val, char *yyyymmdd ) {
    :
    date_val->tm_year = atoi(yyyy) - 1900;
    :

那么您可以使用简单的指针调用它,而无需创建额外的指针变量:

if ( timestr_to_tm ( &t_node->date_one, "19981127" ) < 0 ) {
    ...
于 2013-05-12T20:39:32.100 回答
2

我认为指针取消引用运算符->优先于“地址”运算符

它确实如此,它在取消引用*运算符上也是如此。因此,例如:

*(date_val)->tm_mday = atoi(dd);

应该

(*date_val)->tm_mday = atoi(dd);

但是:你为什么要这样做?为什么不将指针传递给struct tm, 并->没有更多间接级别的情况下使用?

于 2013-05-12T20:19:56.913 回答
1

由于我懒得理解这个问题,我将添加这个不相关的示例,希望有助于澄清问题。如果您使用正确的语法和间接级别,这非常简单。

typedef struct _node node_t;
struct _node {
    node_t* next;
    int     a;
};

void fill_in_int(int* pointer_to_int) {
    *pointer_to_int = 42;
}

void populate_all_nodes(node_t* list, int a_value) {
    node_t* node;

    for (node=list; node; node = node->next) {
        fill_in_int( &(node->a) );       // Pass pointer to member a in node
    }
}
于 2013-05-12T20:41:44.263 回答