编辑代码

#include <stdio.h>
#include <stdarg.h>

#define STR(x) #x
#define STRINGFY(x) STR(x)
// #define MY_STRING __FILE__ ", Line " STRINGFY(__LINE__) ": "
// #define MY_STRING __FILE__ ", Line " STRINGFY(__FUNCTION__) ": "
#define MY_STRING "Date: " __DATE__ "\nTime: " __TIME__ "\nFile: " __FILE__ "\n"
#define LOG_HEX(title, data, len) hexdump(MY_STRING title " hexdump", data, len)

// 'stdout' bellow should be instead with 'stderr' in trusty TA.

#define FPRINT_CORE(fmt, ...) \
    fprintf(stdout, "[%s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)

#define FPRINT_ERROR(fmt...) \
    FPRINT_CORE(fmt)

#define LOG_D(fmt, ...) vfprintf_debug(__FILE__, __LINE__ fmt, ##__VA_ARGS__)

typedef enum {
    DEBUG_LVL = 0,
    ERROR_LVL = 1,
} LogLevel;

void vfprintf_core(LogLevel level, const char* fmt, va_list args) {
    switch (level) {
        case DEBUG_LVL:
            fprintf(stdout, "%s (debug): ", "vfprintf");
            break;
        case ERROR_LVL:
            fprintf(stdout, "%s (error): ", "vfprintf");
            break;
        default:
            fprintf(stdout, "%s (critical): ", "vfprintf");
    }
    vfprintf(stdout, fmt, args);
    fprintf(stdout, "\n");
}

void vfprintf_debug(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    vfprintf_core(DEBUG_LVL, fmt, args);
    va_end(args);
}

void vfprintf_error(char *fmt, ... ) {
       va_list args;
    va_start(args, fmt);
    vfprintf_core(ERROR_LVL, fmt, args);
    va_end(args);
}

void hexdump(const char* title, void* data, int len) {
    printf("%s\n", title);
    for (int i = 0 ; i < len; i++) {
        printf("%c", *(char*)(data + i));
    }
    printf("\n");
}

int main () { 
    printf("C languare \"fprintf\" and \"vfprintf\" usage learning.\n");

    printf("\n----------- hexdup -----------\n");
    char data[] = "Welcome to this world.";
    LOG_HEX("Some Messages", data, sizeof(data));
    printf("__FUNCTION__ (%s) is string variable.\n", __FUNCTION__);

    int value = 0;

    printf("\n----------- fprintf -----------\n");
    value = 20;
    FPRINT_CORE("fprintf with value: %d.", value);
    FPRINT_CORE("fprintf without value.");

    value = 23;
    FPRINT_ERROR("fprintf with value: %d.", value);
    FPRINT_ERROR("fprintf without value.");

    printf("\n----------- vfprintf -----------\n");
    value = 11;
    vfprintf_debug("Has value: %d.", value);
    vfprintf_debug("No value.");

    value = 28;
    vfprintf_error("Has value: %d.", value);
    vfprintf_error("No value.");



    return 0;
}