Ho cercato in giro qualcosa come “write log file in C like printf” senza grandi risultati, o meglio: nulla di “prefatto”, ho realizzato una cozzaglia di codice trovato qua e là, realizzando quanto propongo.
In pratica desideravo qualcosa di semplice, non mi serviva utilizzare chissà quale libreria o funzionalità impestata, sostanzialmente: volevo scrivere su un file di testo una stringa “formattata” passando i parametri come fosse una “printf”.
Sì, detta così è un po’ criptica la faccenda, ma se qualcuno cerca di risolvere questo problema – probabilmente – capisce cosa intendo dire.
Mi aspetto che lo capisca almeno dal codice che ho scritto:
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define MAXBUFFERSIZE 2048
int print_log(const char *log_file, // Path of log file
const char log_msg_type, // Letter of Log Type (ex: I = Info, A = Alert, E = Error)
const char *format, // Parameters like printf
...
) {
va_list arg;
int done;
char psBuffer[MAXBUFFERSIZE];
char psLogData[MAXBUFFERSIZE * 2];
char psTime[MAXBUFFERSIZE];
time_t t; // not a primitive datatype
struct tm *tmp;
memset(psBuffer, '\0', MAXBUFFERSIZE - 1);
memset(psLogData, '\0', (MAXBUFFERSIZE * 2) - 1);
memset(psTime, '\0', MAXBUFFERSIZE - 1);
va_start (arg, format);
done = vsnprintf(psBuffer, MAXBUFFERSIZE - 2, format, arg);
va_end (arg);
time(&t);
tmp = localtime(&t);
if (tmp == NULL) {
perror("localtime");
exit(EXIT_FAILURE);
}
strftime(psTime, MAXBUFFERSIZE - 1, "%F %T", tmp);
sprintf(psLogData, "[%c] %s :: %s\n", log_msg_type, psTime, psBuffer);
FILE* fp;
fp = fopen(log_file, "a+");
fputs(psLogData, fp);
fclose(fp);
return done;
}
Per usare il tutto è sufficiente salvare il codice di cui sopra in un file che potrebbe chiamarsi “printlog.h” e quindi usarlo in qualcosa di simile a questo:
#include "printlog.h"
int main (int argc, char **argv) {
print_log("/tmp/test.log", 'I', "Parametro: %s", argv[1]);
return EXIT_SUCCESS;
}
Il programma di test l’ho salvato in “printlog.c” e compilato (su Linux Debian) con questo comando:
gcc -o printlog printlog.c
Spero sia utile a qualcuno, fatemi sapere.
PS: Se uno guarda bene il codice, si accorgerà che fa un po’ schifo, soprattutto nella gestione della dimensione massima delle stringhe, ma avevo fretta…