Variablen aus .conf File auslesen
-
Hallo,
als völliger Neuling in C-Programmierung habe ich folgendes Problem:
Aus einer Datei logger.conf möchte ich Werte auslesen, die anschließend im c-Programm weiterverarbeitet werden.
logger.conf
#BlaBla loginterval = 60 #Blabla DBName = solarmax DBUser = solaruser DBPass = test #BlaBla AnzahlWR = 2 ##Anhängig von AnzahlWR kommen nun die Variablen Hostname und Hostport n-mal. Hostname1 = 192.168.25.1 Hostport1 = 12345 ##Bla Hostname2 = 192.168.25.2 Hostport2 = 23456
Die config-Datei ist gespickt mit Kommentaren (#...)
Meine bisherigen Versuche beschränken sich darauf, wenigstens einen Wert aus der Datei zu lesen und in eine Variable zu schreiben.
logger.c
#include <stdio.h> char* config_file_name = "/usr/local/etc/logger.conf"; int main(int argc, char **argv) { FILE *fp = fopen(config_file_name, "r"); char var[512], line[512]; if (fp) { while (fgets(line, sizeof(line), fp)) { if (sscanf(line, "DBPass = %[^\n]", var)) { printf("Datenbank-Passwort = %s\n", var); } fclose(fp); } return 0; } }
Leider sind meine Versuche bisher nicht von Erfolg gekrönt.
Die weiteren Schritte sollen dann sein:
- alle Variablen auslesen
- den Dateinamen optional aus Aufrufparameter auszulesenHoffentlich kann mir hier jemand helfen.
Vielen Dank im Voraus.
-
Texte in C parsen ist schrecklich. Ich würde was fertiges suchen, z.B:
http://www.compuphase.com/minini.htm
-
Ich habe irgendwann vor vielen Jahren mal sowas geschrieben. Ich habe allerdings nur noch eine .patch Datei davon, daher hier mal die Datei: http://feig.privatepaste.com/3951c6f9ea
Irgendwo ab "Config Parser (configfile.c)" beginnt der Code.
if(strstr(buffer, "\";")) sscanf(buffer, "%[^= ] = \"%[^\";]", key, data);
ist dabei quasi das, was du suchst. Dabei müsste die Config so aussehen:
// Kommentar
abc = "def";Vielleicht hilft dir der Code ja ein bisschen weiter, auch wenn er schon etwas älter ist.
-
Ich bin nun insofern ein Stück weiter, als dass ich zumindest die gleichbleibenden Variablen-Namen (global-settings) abfragen kann.
logger.conf
#Settings for the Solarmax Watcher #Global-settings loginterval=60 DBUser=solaruser DBName=solarmax DBPass=test Inverter_count=3 #Inverter1 Hostname1=192.168.25.2 Hostport1=12345 #Inverter2 Hostname2=192.168.25.3 Hostport2=23456 #Inverter3 Hostname3=192.168.25.4 Hostport3=34567
Wie kann ich die denn nur erfragen?
Hier mein bisheriger Code (logger.c)
#include <stdio.h> #include <string.h> char* config_file_name = "/usr/local/etc/logger.conf"; int main(int argc, char **argv) { FILE *fp = fopen(config_file_name, "r"); char var1[512], var2[512], var3[512], var4[512], var5[512], line[512]; if (fp) { while (fgets(line, sizeof(line), fp)) { if (sscanf(line, "DBName=%[^\n]", var1)) { printf("DBName = %s\n", var1); } if (sscanf(line, "DBUser=%[^\n]", var2)) { printf("DBUser = %s\n", var2); } if (sscanf(line, "DBPass=%[^\n]", var3)) { printf("DBUPassword = %s\n", var3); } if (sscanf(line, "loginterval=%[^\n]", var4)) { printf("LogInterval = %s\n", var4); } if (sscanf(line, "Inverter_count=%[^\n]", var5)) { printf("Anzahl Wechselrichter = %s\n", var5); } } return 0; } fclose(fp); }
Vielen Dank für die bisherigen Hinweise
-
Alles sehr einfach, z.B.:
int lies(const char *fname,Paar *conf,size_t cs) { int r=0; char zeile[1000],*p; FILE *f=fopen(fname,"rt"); if(!f) return perror(fname),r; while( fgets(p=zeile,1000,f) ) { if( strchr(p,'\n') ) *strchr(p,'\n')=0; if( p=strchr(zeile,'='),1==sscanf(zeile,"%[^ \t#]=",zeile) ) { size_t i=cs; while( i-- ) if( !strcmp(conf[i].key,zeile) ) ++r,sprintf(conf[i].val,"%.*s",sizeof conf->val-1,p+1); } } fclose(f); return r; }
und aufrufen z.B.:
typedef struct { char key[20],val[100]; } Paar; ... Paar conf[]={{"DBName"},{"DBUser"},{"DBPass"}}; size_t s=sizeof conf/sizeof*conf; lies("conf.txt",conf,s); while( s-- ) puts(conf[s].key),puts(conf[s].val);
Anpassen müsstest du noch, falls du Sektionen "[]" in deiner ini-Datei nutzt.
-
@wutz ich finde deinen code nicht so schön, musst du immer alles in eine zeile quetschen? das machts doch nicht wirklich lesbarer...
kann nur hoffen dass ein compiler das raus optimieren kann...
if( strchr(p,'\n') ) *strchr(p,'\n')=0;
-
Wow, das überfordert mich total. Hab verducht deinen Code in mein Programm zu integrieren. Ich weiss aber gar nicht so recht wie, da ich den Code nicht verstehe. Sorry, bin halt noch ein Grünschnabel.
-
Dazu sind Funktionen übrigens da, dass sie Funktionalitäten kapseln.
Der Anwender, also du braucht sich nur um den aufrufenden Kontext sprich um seine eigentlichen Sachen kümmern, womit er meist genug zu tun hat und sich nicht um solche Basisfunktionalitäten kümmern.2x Copy+Paste sollten doch wohl nicht zuviel verlangt sein; die Funktion gibt die Zahl der erfolgreichen Zuordnungen zurück und prüft auch noch auf val-Länge und schneidet wenn nötig ab.