【问题标题】:C Pass multiple strings and numbers as argument listC传递多个字符串和数字作为参数列表
【发布时间】:2021-03-22 04:42:02
【问题描述】:

我想知道这是否可行。 我有一个函数可以用时间和日期将一行写入日志文件,但目前如果我只能给它一个字符串,我必须使用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吗? I've been trying a few things like using cstdarg and passing it multiple arguments but it either doesn't work or runs forever你试过什么?它是 C 中的 #include <stdarg.h>
  • 使用sprintf 是实现这一目标的最简单方法。编写你自己的 printf 类可变参数函数稍微复杂一些。
  • 查看我的回答:codereview.stackexchange.com/questions/249042/… 它的功能与您正在寻找的类似(包括使用 stdarg.h
  • @KamilCuk 是的,我确实尝试了 stdarg,但它运行在同样的问题中。我也尝试将一个完整的数组传递给它,但如果不使用另一个函数,我无法获得其中的数字。至于vprintf,没见过,我去看看。
  • I did try the stdarg, but it runs in the same problem 什么问题?你是如何“使用”它的?它应该像fprintf(mylog, "%s :: %s..."); va_list; va_start(va, append); fvprintf(mylog, message, va); va_end(va); 一样简单

标签: c function arguments


【解决方案1】:

只需使用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

【讨论】:

  • 您好,感谢您的帮助。我正在使用 vprintf 尝试它,就像 KamilCuk 之前评论的那样,但我想我做错了什么,因为我的实现没有奏效。我确实有一个棘手的问题,我接受了你关于什么是论点的建议,但我不明白为什么我不应该打开/关闭文件。如果我不这样做,如果程序意外关闭会不会出现问题?
  • 致电fflush()。问题是需要时间——这是多余的。无论如何,当程序关闭时文件也会关闭。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 2012-07-17
  • 2015-06-02
  • 2022-10-16
  • 2012-11-15
相关资源
最近更新 更多