Autore: Fabio Di Matteo
Ultima revisione: 01/07/2008
Spesso i software utilizzano file di testo per memorizzare le impostazioni e le preferenze.
Questi file di solito hanno una struttura simile:
#I commenti iniziano per # e possono servire per disabilitare una chiave key0 zero key1 uno #key2 due #Questo è soltanto un commento key3 tre key4 quattro key5 cinque
dove keyn
è il nome del valore, invece zero, uno,due … il valore.
Per ineragire con questi file sono necessarie funzioni come le seguenti:
char* keyread(char *path, char* key); void keywrite(char *path, char* key, char* value); int keydel(char *path, char* key);
Ci serviranno 3 funzioni, una per leggere le chiavi, una per scriverle e l'altra per cancellarle.
#include <string.h> #define MAXKEY 50 #define MAXVALUE 50 #define MAXLINE 256 int wordcount(char* line); char* keyread(char *path, char* key); void keywrite(char *path, char* key, char* value); int keydel(char *path, char* key); char* keyread(char *path, char* key){ FILE *f=fopen(path, "r"); char valuetmp[MAXVALUE], line[MAXVALUE+MAXKEY], *value, key_now[MAXKEY] ; int i; while (feof(f)==0){ fgets(line,MAXVALUE+MAXKEY,f); if (line[0]!='#' && wordcount(line)==2){ sscanf(line, "%s %s\n",key_now, valuetmp); if (strcmp(key_now, key)==0){ value=malloc(sizeof(valuetmp)); strcpy(value,valuetmp); return value; } } } fclose(f); } void keywrite(char *path, char* key, char* value){ FILE *f=fopen(path, "r"); int i, pos=0, idxline=0 ; char valuetmp[MAXVALUE], line[MAXVALUE+MAXKEY], *nline[MAXVALUE+MAXKEY], key_now[MAXKEY] ; //get key's position while (feof(f)==0){ pos++; nline[pos-1]=malloc(MAXLINE); fgets(nline[pos-1],MAXLINE,f); if (nline[pos-1][0]!='#' && wordcount(nline[pos-1])==2){ sscanf(nline[pos-1], "%s %s\n",key_now, valuetmp); if (strcmp(key_now, key)==0 && idxline==0){ idxline=pos-1; } } } fclose(f); //edit or append key nline[idxline]=malloc(sizeof(key)+sizeof(value)+1); if (idxline!=0){ //edit key sprintf(nline[idxline] ,"%s %s\n",key,value); FILE *f=fopen(path, "w"); for (i=0;i<=pos-1;i++) fputs(nline[i],f); fclose(f); }else{ //append new key FILE *f=fopen(path, "a"); sprintf(nline[pos-1] ,"%s %s\n",key,value);; fputs(nline[pos-1],f); fclose(f); } } int keydel(char *path, char* key){ FILE *f=fopen(path, "r"); int i, pos=0, idxline=0 ; char valuetmp[MAXVALUE], line[MAXVALUE+MAXKEY], *nline[MAXVALUE+MAXKEY], key_now[MAXKEY] ; //get key's position while (feof(f)==0){ pos++; nline[pos-1]=malloc(MAXLINE); fgets(nline[pos-1],MAXLINE,f); if (nline[pos-1][0]!='#' && wordcount(nline[pos-1])==2){ sscanf(nline[pos-1], "%s %s\n",key_now, valuetmp); if (strcmp(key_now, key)==0 && idxline==0){ idxline=pos-1; } } } fclose(f); //delete key nline[idxline]=malloc(sizeof(key)+MAXVALUE+1); if (idxline!=0){ FILE *f=fopen(path, "w"); for (i=0;i<=pos-1;i++){ if (i!=idxline)fputs(nline[i],f); } fclose(f); }else{ return -1; } } int wordcount(char* line){ int i,count=0; for(i=0; i<strlen(line);i++){ if (isspace(line[i]) && !isspace(line[i+1]) ) count++; } return count; }
Ecco una tipica main() che potrebbe sfruttare le funzioni.
L'eseguibile si userà in questo modo:
keys -r [chiave]
per leggere il valore della chiave;
keys -w [chiave] [valore]
per assegnare un valore ad una chiave (se la chiave non esiste la crea) ;
keys -d [chiave]
per eliminare la chiave;
#include <stdio.h> #include "keys.c" #define PREF "preference.conf" int main(int *argc, char *argv[]){ if (argc>2){ if (argv[1][1]=='r'){ char *valore=keyread(PREF , argv[2]); printf("%s\n",(valore!=NULL ? valore:"0")) ; } if (argv[1][1]=='w'){ keywrite(PREF,argv[2], argv[3] ); } if (argv[1][1]=='d'){ if (keydel(PREF,argv[2])==-1) printf("key not present!\n") ; } }else{ printf("USAGE: keys -r or -w arg1 [arg2]\n "); } return 0; }
Commentiamo soltanto la funzione keyread in quanto le altre funzioni sono un surrogato della stessa, soltato che scrivono invece che leggere dal file.
La funzione keyread restituisce un puntatore a char contenente il testo del valore che vogliamo prendere oppure NULL
se non trova la chiave o la chiave è scritta in un formato sbagliato.
Ecco il codice di keyread commentato:
char* keyread(char *path, char* key){ FILE *f=fopen(path, "r"); char valuetmp[MAXVALUE], line[MAXVALUE+MAXKEY], *value, key_now[MAXKEY] ; int i; while (feof(f)==0){ / fgets(line,MAXVALUE+MAXKEY,f);//finchè non finisce il file metti ogni riga in array /*se nella riga corrente non ci sono commenti e se nella riga ci sono 2 parole soltanto (chiave +valore)*/ if (line[0]!='#' && wordcount(line)==2){ /*metti il nome della chiave in key_now e il valore in valuetmp*/ sscanf(line, "%s %s\n",key_now, valuetmp); /*se key_now corrisponde alla chiave che cerchiamo ritorna il valore della chiave*/ if (strcmp(key_now, key)==0){ value=malloc(sizeof(valuetmp)); strcpy(value,valuetmp); return value; } } } fclose(f); }
Il nostro wiki installa solamente cookie tecnici necessari al funzionamento della piattaforma "Dokuwiki". Niente analitics, statistiche, tracciamenti o altro.