как получить timestamp в c

Я хочу получить временную метку для моего входа в систему c. Я написал функцию, чтобы получить метку времени. Но когда я возвращаю переменную im, получаю другую ценность.

Мой код:

#include  #include  #include  char* get_timestamp(){ time_t rawtime; struct tm * timeinfo; char buffer[16]; time (&rawtime); timeinfo = localtime (&rawtime); strftime (buffer,16,"%G%m%d%H%M%S",timeinfo); puts(buffer); return buffer; } int main() { puts(get_timestamp()); return 0; } 

выход:

 20130315204815 Ir?0315204815 

Может ли кто-нибудь помочь в этом … Спасибо.

Вы возвращаете указатель на переменную стека, и поэтому он недействителен для использования после возвращения функции:

  char buffer[16]; 

Будет выделено в стеке в функции. Когда вы возвращаете стек, очищается, а buffer больше недействителен. С минимальными изменениями это, вероятно, лучшая сигнатура функции:

 void get_timestamp( char *buffer, size_t buffLen ) 

Предполагалось, что вы правильно get_timestamp пространство для buffer перед вызовом get_timestamp .

buffer[16] – локальный массив, который останавливается в конце функции char* get_timestamp() . Затем вы возвращаете указатель на массив, который не существует.

Как сказал другой, вы используете данные, которые находятся в стеке, и останавливаются после того, как вы оставите функцию, объявившую ее. Я вижу две простые возможности для решения этой проблемы:

Вариант 1: выделить буферную переменную в вызывающей функции и передать указатель в get_timestamp

 void get_timestamp( char *buffer, size_t buffersize ) { .... strftime (buffer,buffersize,"%G%m%d%H%M%S",timeinfo); } int main() { char buffer[16]; puts(get_timestamp(buffer,16)); return 0; } 

Примечание / Редактирование: я сбрасывал очень верное замечание относительно передачи размера буфера в это предлагаемое решение.

Вариант 2: если вы не можете или не хотите менять подпись своей функции, вы можете использовать статическую переменную, но не забывайте, что статические переменные могут вызывать проблемы в многопоточных программах.

 static char buffer[16]; char* get_timestamp(){ ... } int main() { puts(get_timestamp()); return 0; } 

Разумеется, вы можете использовать malloc но в этой ситуации это кажется излишним и более подвержено ошибкам, чем два описанных мной исправления.

Строка, которую вы возвращаете, является автоматической переменной. Когда вы выходите из функции, доступ к этой переменной невозможно. Согласно спецификациям это неопределенное поведение. Используйте malloc для выделения строки, и все будет хорошо. Просто не забудьте освободить его потом.

Отвечая на этот вопрос, я хотел, чтобы функция была простой, дружественной к streamу, не возвращала char * (что часто бывает утомительно для управления), streamобезопасным и может стоять на своих собственных ногах. У меня есть отrotation к функциям, возвращающим char * или указатели, которым нужно управлять.

Функция ниже не вызывает malloc.

Функция не принимает никаких параметров и возвращает метку времени. Я думаю, что это работает хорошо.

 struct Timestamp { time_t seconds; long milliseconds; char timestring[32]; }; struct Timestamp getTimestamp() { char timebuffer[32] = {0}; struct timeval tv = {0}; struct tm *tmval = NULL; struct tm gmtval = {0}; struct timespec curtime = {0}; struct Timestamp timestamp; int i = 0; // Get current time clock_gettime(CLOCK_REALTIME, &curtime); // Set the fields timestamp.seconds = curtime.tv_sec; timestamp.milliseconds = round(curtime.tv_nsec/1.0e6); if((tmval = gmtime_r(&timestamp.seconds, &gmtval)) != NULL) { // Build the first part of the time strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval); // Add the milliseconds part and build the time string snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds); } return timestamp; } int main() { char timebuffer[64] = {0}; int i = 0; struct timespec sleeptime = {0, 5000000L}; struct Timestamp timestamp; for (i=0; i < 20; i++) { timestamp = getTimestamp(); printf("Time is: %s \n", timestamp.timestring); nanosleep(&sleeptime, NULL); } return 0; }