我想获取登录c的时间戳。 我写了一个函数来获取时间戳。 但是当我返回变量时,我得到了不同的值。
我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
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
任何人都可以帮忙...谢谢你。
答案 0 :(得分:6)
buffer[16]
是一个本地数组,它会在char* get_timestamp()
函数结束时停止存在。然后返回一个指向不存在的数组的指针。
答案 1 :(得分:5)
您正在返回指向堆栈变量的指针,因此在函数返回后无效:
char buffer[16];
将在函数的堆栈中分配。当您返回时,清理堆栈并且buffer
不再有效。只需极少的更改,这可能是一个更好的功能签名:
void get_timestamp( char *buffer, size_t buffLen )
假设您在致电buffer
之前已为get_timestamp
正确分配了空间。
答案 2 :(得分:2)
正如另一个所说,你将使用驻留在堆栈上的数据,并在离开声明它的函数后停止存在。我看到两个简单的可能性来解决这个问题:
选项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
,但在这种情况下这似乎有点过头了,而且比我描述的两个修复更容易出错。
答案 3 :(得分:1)
您要返回的字符串是一个自动变量。退出函数时,无法访问此变量。根据规格,它是未定义的行为。使用malloc分配字符串,你会没事的。 只是不要忘记随后将其释放。
答案 4 :(得分:1)
在回答这个问题时,我想要一个简单,线程友好,不返回char *(通常很难管理)的函数,线程安全且可以自立。我厌恶返回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(×tamp.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;
}