C 传递多个字符串和数字作为参数列表
C Pass multiple strings and numbers as argument list
我想知道是否完全可行。
我有一个函数可以用时间和日期将一行写入日志文件,但目前如果我只能给它一个字符串,我必须使用 snprintf
创建一个自定义字符串并像那样传递它。这确实工作得很好,但我希望能够传递我需要的所有变量,并给它一个字符串来记录和可能的一些变量。
这是函数
void myLog(char logLevel, char * file, int line, char * message, char append)
{
char dateTime[22];
time_t myTime = time(NULL);
char * logLevelString;
FILE * myLog;
switch (logLevel)
{
case 1:
logLevelString = "INFO";
break;
case 2:
logLevelString = "WARN";
break;
case 3:
logLevelString = "CRIT";
break;
default:
logLevelString = "-ERR";
break;
}
strftime(dateTime, 22, "%H:%M:%S - %d/%m/%Y", localtime(&myTime));
myLog = fopen("Output.log", append ? "a" : "w");
fprintf (myLog, "%s :: %s :: File: %s (line: %d) :: %s\n", logLevelString, dateTime, file, line, message);
fclose(myLog);
}
我这样称呼它:myLog(1, __FILE__, __LINE__, "Opening & clearing log file success.", 0);
如果我需要字符串中的一些其他变量,我会这样做:snprintf(buffer, 100, "Running game %i / %i", i + 1, MAX_GAMES);
然后传递缓冲区。
我希望函数做的是一次获取所有字符串并自己创建新字符串,这样我就可以这样调用它:myLog(1, __FILE__, __LINE__, "Running game %i / %i", i + 1, MAX_GAMES, 1);
我一直在尝试一些事情,例如使用 cstdarg 并向其传递多个参数,但它要么不起作用,要么永远运行(好吧,直到它停止整个程序)。我也在网上发现了一些类似的东西,但它们要么使用所有数字或字符串,但我需要向它传递一个字符串,然后传递一些数字或更多字符串。
有没有办法做到这一点,还是我应该继续使用 snprintf 创建字符串?
只需使用vprintf
:
#idef __GNUC__
// on gcc will enable warnings, just like for printf
__attribute__((__format__(__printf__, 4, 6)))
#endif
void myLog(char logLevel, const char * file, int line, const char *fmt, char append, ...) {
// ... rest of your code here ...
if (myLog == NULL) /* handle errors! */ abort();
fprintf(myLog, "%s :: %s :: File: %s (line: %d) :: ", logLevelString, dateTime, file, line);
va_list;
va_start(va, append);
fvprintf(myLog, fmt, va);
va_end(va);
fprintf(myLog, "\n");
// ...
}
int main() {
myLog(1, __FILE__, __LINE__, "Normal %s %s %llu", 1, "format", "string", 1llu);
}
我建议将参数的顺序更改为 char append, const char *fmt, ...)
,以便 printf 格式字符串接近 ...
。我还建议不要每次都打开日志文件,而是保持打开状态。如果可以重入,也使用 localtime_r
。
我想知道是否完全可行。
我有一个函数可以用时间和日期将一行写入日志文件,但目前如果我只能给它一个字符串,我必须使用 snprintf
创建一个自定义字符串并像那样传递它。这确实工作得很好,但我希望能够传递我需要的所有变量,并给它一个字符串来记录和可能的一些变量。
这是函数
void myLog(char logLevel, char * file, int line, char * message, char append)
{
char dateTime[22];
time_t myTime = time(NULL);
char * logLevelString;
FILE * myLog;
switch (logLevel)
{
case 1:
logLevelString = "INFO";
break;
case 2:
logLevelString = "WARN";
break;
case 3:
logLevelString = "CRIT";
break;
default:
logLevelString = "-ERR";
break;
}
strftime(dateTime, 22, "%H:%M:%S - %d/%m/%Y", localtime(&myTime));
myLog = fopen("Output.log", append ? "a" : "w");
fprintf (myLog, "%s :: %s :: File: %s (line: %d) :: %s\n", logLevelString, dateTime, file, line, message);
fclose(myLog);
}
我这样称呼它:myLog(1, __FILE__, __LINE__, "Opening & clearing log file success.", 0);
如果我需要字符串中的一些其他变量,我会这样做:snprintf(buffer, 100, "Running game %i / %i", i + 1, MAX_GAMES);
然后传递缓冲区。
我希望函数做的是一次获取所有字符串并自己创建新字符串,这样我就可以这样调用它:myLog(1, __FILE__, __LINE__, "Running game %i / %i", i + 1, MAX_GAMES, 1);
我一直在尝试一些事情,例如使用 cstdarg 并向其传递多个参数,但它要么不起作用,要么永远运行(好吧,直到它停止整个程序)。我也在网上发现了一些类似的东西,但它们要么使用所有数字或字符串,但我需要向它传递一个字符串,然后传递一些数字或更多字符串。
有没有办法做到这一点,还是我应该继续使用 snprintf 创建字符串?
只需使用vprintf
:
#idef __GNUC__
// on gcc will enable warnings, just like for printf
__attribute__((__format__(__printf__, 4, 6)))
#endif
void myLog(char logLevel, const char * file, int line, const char *fmt, char append, ...) {
// ... rest of your code here ...
if (myLog == NULL) /* handle errors! */ abort();
fprintf(myLog, "%s :: %s :: File: %s (line: %d) :: ", logLevelString, dateTime, file, line);
va_list;
va_start(va, append);
fvprintf(myLog, fmt, va);
va_end(va);
fprintf(myLog, "\n");
// ...
}
int main() {
myLog(1, __FILE__, __LINE__, "Normal %s %s %llu", 1, "format", "string", 1llu);
}
我建议将参数的顺序更改为 char append, const char *fmt, ...)
,以便 printf 格式字符串接近 ...
。我还建议不要每次都打开日志文件,而是保持打开状态。如果可以重入,也使用 localtime_r
。