我创建了一个用于创建时间戳的小型C程序,并将其附加到文件文本名称:
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
void time_stamp(){
time_t rawtime;
struct tm * timeinfo;
char buffer [80];
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (buffer,80,"myFile_%F.txt",timeinfo);
printf ("%s", buffer);
}
int main ()
{
void (*filename_ptr)();
filename_ptr = &time_stamp;
FILE * fp;
fp = fopen (filename_ptr, "w+");
fprintf(fp, "%s %s %s %d", "We", "are", "in", 2017);
fclose(fp);
return 0;
}
但是我不能让fopen接受指向带有时间戳创建名称的函数的指针。它期待一个const char。我如何将函数指针转换为它?
答案 0 :(得分:2)
你不能,但你可以通过附加()
的指针调用该函数。为此,请将您的功能更改为实际返回const char *
(或char *
)
请注意,您不能只返回指向buffer
的指针,因为这是一个在函数返回时不再存在的局部变量。您可以从函数外部传递指向buffer
的指针。那么你的原型应该是
char *time_stamp(char *buf, size_t len);
修改后的代码:
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
char *time_stamp(char *buf, size_t len){
time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (buf,len,"myFile_%F.txt",timeinfo);
return buf;
}
int main ()
{
char *(*filename_ptr)(char *, size_t);
filename_ptr = &time_stamp;
char buffer[80];
FILE * fp;
fp = fopen (filename_ptr(buffer, 80), "w+");
fprintf(fp, "%s %s %s %d", "We", "are", "in", 2017);
fclose(fp);
return 0;
}
如何设计此功能还有其他选择。当您确定在线程上下文中永远不需要该函数时,Neroku的答案是好的。它简化了使用,甚至还有一些以这种方式设计的标准C库函数。
第三种方法是通过从malloc()
获取缓冲区来使缓冲区成为分配的对象。这具有线程安全且不需要任何额外参数的优点,该函数本身控制缓冲区的大小,就像在原始破坏版本中一样。缺点是调用者在完成后必须free()
内存。示例代码(我不建议这里):
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
char *time_stamp(){
time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime (&rawtime);
char *buf = malloc(80);
strftime (buf,80,"myFile_%F.txt",timeinfo);
return buf;
}
int main ()
{
char *(*filename_ptr)();
filename_ptr = &time_stamp;
FILE * fp;
char *filename = filename_ptr();
fp = fopen (filename, "w+");
free(filename);
fprintf(fp, "%s %s %s %d", "We", "are", "in", 2017);
fclose(fp);
return 0;
}
答案 1 :(得分:2)
fopen()
期望const char *
作为第一个参数:
FILE *fopen(const char *path, const char *mode);
在您的函数time_stamp()
中,您打印时间戳并且不返回任何内容,即:void
。
您可以使用新的time_stamp()
功能(请注意static
声明中的buffer
):
const char* time_stamp(){
time_t rawtime;
struct tm * timeinfo;
static char buffer [80];
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (buffer,80,"myFile_%F.txt",timeinfo);
return buffer;
}
然后,您可以在调用fopen()
时调用此新功能。 time_stamp()
返回的值将变为fopen()
的第一个参数:
const char * (*filename_ptr)();
filename_ptr = &time_stamp;
// ...
fp = fopen (filename_ptr(), "w+");
请注意,从time_stamp()
返回的值的类型现在匹配fopen()
期望的第一个参数的类型(即:const char *
)。
由于函数time_stamp()
包含静态分配的存储(buffer
),因此在多线程程序中使用此函数是不安全的,因为所有线程调用此函数将共享此存储的单个实例。