2016-10-21 3 views
0

Я использую ctime. Однако он всегда возвращает NULL. Таким образом, он работает на линии sprintf. Он работал раньше. Итак, не уверен, почему он случайно возвращает NULL?ctime возвращает NULL случайным образом

У меня есть следующий фрагмент кода:

int main() 
{ 
    char avp_val[50]; 

    uint32_t date_value=1477069401; 

    sprintf(avp_val,"%s",ctime((time_t*)(&date_value))); 

    return; 
} 
+4

Почему вы используете 'uint32_t' вместо' time_t'? Если вы использовали правильный (и, вероятно, 64-битный) тип, вам не понадобится уродливый и ненадежный листинг, не так ли? О, и 'return;' вместо 'return 0;' еще одна ошибка - вы должны вернуть значение. –

+0

Возможно, вы захотите переместить вызов 'ctime' в отдельную строку. Таким образом, вы можете проверить возвращаемое значение из 'ctime' и убедиться, что оно выполнено успешно, прежде чем передать результат в' sprintf'. – user3386109

+0

Благодарим за отзыв. Я читаю байты из pkt. SO i читает 4 байта, которые представляют эту дату, и их нужно преобразовать в читаемый человеком формат. Это была jyst тестовая программа, так что не волнует возвращение; :) – Gauri

ответ

5

Не бросить указатель uint32_t к time_t. Используйте фактическую time_t, так и на системы с 64-битной time_tctime не читает четыре байта мусора, как часть времени эпохи:

int main() 
{ 
    char avp_val[50]; 

    time_t date_value=1477069401; 

    sprintf(avp_val,"%s",ctime(&date_value)); 
    // Or, because it's what you're doing anyway, skip sprintf: 
    // strcpy(avp_val, ctime(&date_value)); 

    return 0; 
} 

литейного (time_t*) заглушить предупреждения компилятора замолчать предупреждения, он не сделал решить проблему.

+0

И, @Gauri, просто чтобы быть ясным: предупреждение, которое вы получаете без броска, - это предупреждение, которое говорит вам, что у вас есть проблема! ctime возвращает NULL, потому что ожидает указатель на 8-байтовый time_t, но вы передаете указатель на 4-байтовый uint32_t. –

+0

@SteveSummit: Ну, 'NULL' из' ctime' не потому, что он распознает, что вы передали ему указатель на неправильный тип. Это связано с тем, что четыре лишних байта, которые он читает, в то время как технически читаемые (если они не были, вы бы по ошибке), имеют значения нежелательной почты. 'ctime' взрывается, когда он понимает, что дата, представленная этой меткой времени, встречается в году 212,321,423,324 CE (произвольно выбранный из диапазона значений, которые может представлять 64-битный' time_t'). 'ctime' имеет проблему Y10K. :-) – ShadowRanger

+0

Спасибо за ваши комментарии. да, я ошибался. – Gauri

0

Ну, ваш код не имеет кучу включаемых файлов:

#include <stdlib.h> /* for the types you use below, like uint32_t */ 
#include <stdio.h> /* for a prototype for sprintf, which you use below */ 
#include <time.h> /* for a prototype for ctime() see NOTE 1 */ 

Вы также должны учитывать, что литье должно быть сделано со значениями данных, а не с указателями, как отливка указатель только минует тип компилятора проверяя систему и делает ваш код более подверженным ошибкам. В этом случае преобразование с uint32_t * в time_t * слишком опасно, если оба типа имеют разные размеры, так как вы будете сокращать значение, используя только половину необходимых бит. Это что-то знает как Undefined Behavior, и вы должны его избегать.

Вы также должны вернуть явное значение из основного. Это ошибка компиляции не делать этого, так что ваш пример не может выполнить, так как он не компилируется (и таким образом, вы не можете получить NULL от ctime(3))

Кстати, я попробовал ваш код с uint32_t date_value в Mac OS/X, и он напечатал правильное значение времени, поэтому, вероятно, time_t - это 32-битное значение, но вам лучше использовать time_t, поскольку он определяется по этой причине.

Примечание 1

Наиболее важным в данном случае является прототипом CTime(), которая возвращает указатель на char и без прототипа, компилятор предполагает, что это возвращает int. По крайней мере, на 64-битных платформах оба типа имеют разные размеры и не могут быть переданы таким образом.

Пожалуйста, всегда отправляйте пример Complete, minimum, verifiable, так как вы можете скрыть точный источник ошибки, отредактировав свой пример для показа.

Смежные вопросы