找回密码
 register

QQ登录

只需一步,快速开始

查看: 19|回复: 0

[C语言] C语言日志创建文件函数练手 自定义函数 logSuccess

[复制链接]

[C语言] C语言日志创建文件函数练手 自定义函数 logSuccess

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:104
  • 打卡月天数:27
  • 打卡总奖励:103
  • 最近打卡:2025-01-31 22:23:22
Waylee

主题

0

回帖

1万

积分

仙帝

积分
13021
Waylee 2025-1-25 09:24 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <stdbool.h>

void logSuccess(char *format, ...)
{
    bool dir_missing;
    struct stat v2;
    char s[1024] = {0};
    FILE *stream = NULL;
    const char *log_filename = "XuewuSo.txt";
    char *log_directory = "/home/tlbb/Server/Log";
    va_list va;

    va_start(va, format);
    snprintf(s, sizeof(s), "%s/%s", log_directory, log_filename);

    dir_missing = stat(log_directory, &v2) != 0 && errno == ENOENT;
    if (dir_missing)    //&& mkdir(log_directory, 0755)
    {
        perror("Failed to create log directory");
    }
    else
    {
        stream = fopen(s, "a");
        if (stream)
        {
            vfprintf(stream, format, va);
            fputc('\n', stream);
            fclose(stream);
            printf("Success log written to %s\n", s);
        }
        else
        {
            perror("Failed to open log file");
        }
    }
    va_end(va);
}

int main()
{
    logSuccess("This is a test message: %d", 42);
    return 0;
}

代码解析

变量和头文件部分

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdbool.h>
  • stdio.h: 用于文件操作(fopen、fclose、fputc)和标准输出(printf)。
  • stdarg.h: 用于处理变长参数的宏和类型(va_list、va_start、va_arg、va_end)。
  • string.h: 提供字符串处理函数(snprintf、memset)。
  • sys/stat.h: 提供 stat 函数和 mkdir 函数,用于检查文件/目录状态和创建目录。
  • errno.h: 用于检查全局错误码 errno。
  • stdbool.h: 提供布尔类型 bool,使代码更具可读性。

函数定义及参数说明

void logSuccess(char *format, ...)

  • 函数名称:logSuccess
  • 参数:
    • char *format:格式化字符串,用于指定日志内容。
    • ...:省略号表示可变参数,支持传入任意数量和类型的额外参数。

局部变量

bool dir_missing;           // 布尔值,用于检查目录是否存在。
char s[1024];             // 字符数组,存储完整的日志文件路径。
char *path;               // 字符串指针,指向日志目录的路径。
const char *log_filename;           // 字符串常量,指向日志文件名。
FILE *stream;             // 文件指针,表示打开的日志文件流。
va_list va;               // 可变参数列表,用于处理 format 之后的参数。

初始化变量和目录路径

va_start(va, format);
memset(s, 0, sizeof(s));
stream = NULL;
v6 = "XuewuSo.log";
path = "/home/tlbb/Server/Log";
  • va_start(va, format):初始化 va,从而可以访问 ... 传入的参数。
  • memset(s, 0, sizeof(s)):将字符数组 s 全部清零,确保它不会有未定义的内容。
  • stream = NULL:初始化文件指针。
  • v6 和 path:分别设置日志文件名和日志目录的路径。

构建日志文件路径

snprintf(s, sizeof(s), "%s/%s", path, v6);
snprintf:格式化并安全地写入字符数组 s,生成完整的日志文件路径,例如:/home/tlbb/Server/Log/XuewuSo.log

检查目录是否存在

dir_missing = stat(log_directory, &v2) != 0 && errno == ENOENT;

stat(log_directory, (int)v2):检查 log_directory 指向的目录是否存在。

  • 如果 stat 返回非零并且 errno 是 ENOENT(值为 2,表示文件/目录不存在),v1 将被设置为 true,表示目录不存在。

打开日志文件并写入日志内容

else
{
    stream = fopen(s, "a");
    if (stream)
    {
        vfprintf(stream, format, va);
        fputc('\n', stream);
        fclose(stream);
        printf("Success log written to %s\n", s);
    }
    else
    {
        perror("Failed to open log file");
    }
}
  • fopen(s, "a"):以追加模式打开日志文件。如果文件不存在,fopen 会创建它。
  • vfprintf:将变长参数列表 va 中的内容写入文件。
  • fputc('\n', stream):追加一个换行符。
  • fclose(stream):关闭文件。
  • 如果打开文件失败,使用 perror 打印错误原因。

清理

va_end(va):清理变长参数列表。

您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-31 23:47 , Processed in 0.105731 second(s), 5 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表