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