在C中做一个记录器

在下面,我尝试log在 C 中创建一个实用程序:

#include <stdio.h>
#include <string.h>

enum LogLevel {DEBUG=10, INFO=20, WARN=30, ERROR=40};
typedef struct logger {
    int level;
    FILE** handlers; // NULL for sentinel
} Logger;
Logger LOGGER;

char* level_str(int level)
{
    switch (level) {
        case DEBUG: return "DEBUG";
        case INFO:  return "INFO";
        case WARN:  return "WARN";
        case ERROR:  return "ERROR";
        default: return "UNKNOWN";
    };
}
void logger(char* msg, int level)
{
    // skip if level is too low or no handlers set up
    if (level < LOGGER.level || !LOGGER.handlers) return;

    // write to each handler
    for (int i=0; LOGGER.handlers[i]; i++)
        fprintf(LOGGER.handlers[i], "[%s] %sn", level_str(level), msg);
}
int main(void)
{
    LOGGER.level = DEBUG;
    FILE* handler1 = stderr;
    FILE* handler2 = fopen("z_log.txt", "w");
    LOGGER.handlers = &handler1;
    LOGGER.handlers[1] = handler2;
    LOGGER.handlers[2] = NULL;
    logger("Hello", INFO);
    return 0;
}

此处的工作代码:https : //onlinegdb.com/SJcoa5C7O。

我的问题主要是关于用这些行添加一些处理程序:

FILE* handler1 = stderr;
FILE* handler2 = fopen("z_log.txt", "w");
LOGGER.handlers = &handler1; // <-----------
LOGGER.handlers[1] = handler2;
LOGGER.handlers[2] = NULL;
logger("Hello", INFO);

我注意到第一个处理程序需要一个内存地址,例如我可以这样做:

LOGGER.handlers = &handler1;

但我不能这样做:

LOGGER.handlers[0] = handler1;

就像我可以使用我设置的连续处理程序一样。为什么会这样?例如,为什么不LOGGER.handlers[0] = handler1设置LOGGER.handlers我认为array[0]解析为的内存地址,&array[0]那不就是初始内存地址吗?还有其他方法可以“初始化”上面的指针吗?

回答

您需要为指向FILEs的指针保留空间:

LOGGER.handlers = malloc(sizeof(*LOGGER.handlers) * 3);

然后:

LOGGER.handlers[0] = handler1;
LOGGER.handlers[1] = handler2;
LOGGER.handlers[2] = NULL;

或者如果您事先知道元素的数量,则定义FILE *handlers[3];而不是FILE** handlers;

  • It depends, your approach is valid (passing a `NULL` as sentinel), but if you kow the max number of elements then is better to use static memory, `FILE *handlers[MAX_HANDLERS];` and pass the number of elements.

以上是在C中做一个记录器的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>