Tudtok ajánlani valami egyszerű megoldást, hogy hogyan tudnék legy egyszerübben beolvasni egy config filet, ami beállítja a program futási paramétereit.
olyansmire gondolok ami feltölti a változókat értékekkel, mint pl bash-ben a ". config.sh"
köszi
- 2834 megtekintés
Hozzászólások
Ha könnyen konfigurálható valamit akarsz, akkor pl. használj egy XML-parsert, vagy Lua-t.
- A hozzászóláshoz be kell jelentkezni
bullshit. mi a francnak XML meg Lua hat mindeki beteg mostmar?
egy sima text file a legtokeletesebb. most kepes lenne linkelni libxml hez csak azert hogy beolvass mondjuk 5 db valtozot?
na ne mar. miert kell ezt?
- A hozzászóláshoz be kell jelentkezni
Nem, mindenki kényelmes. Inkább linkel egy már megírt libet, aminek a töredékére van csak szüksége :-)
- A hozzászóláshoz be kell jelentkezni
nem kell ide semmilyen lib. mindeki megvan baszva ezzel :)
http://www.openbsd.org/cgi-bin/cvsweb/src/usr.sbin/ntpd/parse.y
Itt van pl az OpenNTPD LALR ben irt config parsere. Kicsi, hibaturo es jol szerkesztheto. Es semmilyen uberhaxor libhez nem kell linkelni.
- A hozzászóláshoz be kell jelentkezni
teljesen igazad van, de kíváncsi vagyok, hogy milyen hatékonysággal győzöd meg az embereket úgy általában..
az 'ez bullshit, kussójjá!, én megmondom neked a frankót, mert én _értek_ hozzá' kezdésen mindig mosolygok..:)
- A hozzászóláshoz be kell jelentkezni
mert maskepp nem figyelnek fel az emberek a mondanivalora.
- A hozzászóláshoz be kell jelentkezni
jah.. kivéve, ha nem vesznek komolyan :)
- A hozzászóláshoz be kell jelentkezni
nem kell ide semmilyen lib. mindeki megvan baszva ezzel :)
Gratulálok.
Szánalmas ez a hozzáálás. Ugyebár csakis OpenBSD-ben lehet jó kódot találni.
(http://www.openbsd.org/cgi-bin/cvsweb/src/usr.sbin/ntpd/parse.y
Parser-t pedig ott is csak az ntpd-ben... :))
Na mindegy, ez van.
Azért ha megnézed a forrást, láthatod, hogy ezt a parsert is a yacc generálja.
Azt sem értem, miért baj, ha uberhaxor libhez kellene linkelni, esetleg még talán jobb is lehet...
ps: tudom, h a yacc LALR(1)... csak azért ne keverjük már a fogalmakat... ebben a stílusban...
- A hozzászóláshoz be kell jelentkezni
Hát a konkrét esetre mindenkébben hatékonyabb egy egyszerű textfile \n terminátorokkal, mint egy olyan lib linkelése, aminek a töredékét se használja ki az ember. Nem olyan bonyolult ám 4-5 sort beolvasni egy textfileból, hogy libeket kelljen használni ;-) .
- A hozzászóláshoz be kell jelentkezni
szvsz félreértettél (vagy én bennetek :)): én nem a konkrét példára írtam a külső könyvtárat, hanem általánosságban: előfordulhat, hogy sokat nyerhetsz vele.
Ha csak egyszerű változó=érték párost kell beolvasni, akkor trivi a parser.
(bár ha megnézed a nagyokat, láthatod, hogy a yacc még egyszerű esetben is kikerülhetetlen. :))
- A hozzászóláshoz be kell jelentkezni
A félreértés emberi dolog :-). Láttam én már olyan embert, aki ilyen problémára könyvtárat használt. Persze aztán ilyenkor csak mosolyogni tudok, amikor az ilyen kódot mindenféle optimalizáló flagekkel fordítják. Általánosságban persze hogy jó dolog, én is használom :)
- A hozzászóláshoz be kell jelentkezni
--torolve--*
- A hozzászóláshoz be kell jelentkezni
Ebben tokeletesen igaza van, thuglife-nak... bison/yacc es legalabb valami erdekeset is tanulsz... Ha meg glib-ezel (GTK+), akkor annak is van Lexical pasrser-e...
Zsiraf
p.s.: amugy meg kb ennyi, ha nem akarod tulvarialni:
fscanf(cf, "%32[A-Za-z]", nev);
fscanf(cf, "%*[ \t]%c%*[ \t]", &chr);
if (chr != '=') {
error();
}
switch(config_type(nev)) {
case INT:
fscanf(cf, "%i%c", &var_i, &chr);
...
break;
case STR:
fscanf(cf, "%s%c", var_s, &chr);
...
break;
...
}
if(chr != '\n') {
error();
}
;-) de nyugodtan kiserletezz libxml2-vel ;-)
- A hozzászóláshoz be kell jelentkezni
C vagy C++?
Ha c, akkor a bison/yacc jó választás lehet.
Ha C++, akkor a Boost Spirit-je jó választás lehet.
Persze nem árt, ha nem vagy kezdő c++-ban....
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Nagyon köszi a segítséget... Tutin megtudtam oldani.
De lenne itt még valami.
lenne egy string pl; 00,123,HHU,,0181,,,,22, ......
A pontosvesszők között lévő részt akarom kihalászni változókba. Egész jól megy sscanf-el, de azon mezőkkel nem tudok mit kezdeni, aminek nincs értéke (;; közötti rész).
Ezzel próbálkoztam:
sscanf(data,"%[0-9]%*[,]%[0-9]%*[,]%[A-Z]%*[,]%[0-9]%*[,]%[0-9]%*[,]....",v1,v2,v3,v4,v5...);
A sorrend az adott.
Olyasmire lenne szükségem mint az "awk -F, ...."
Valami egyéb ötlet?
- A hozzászóláshoz be kell jelentkezni
Akkor ne csinálj olyat, ami üres. Kiválasztasz egy értéket (pl.: "---") és úgy csinálod a parsert, hogy ha ezt találja, akkor ne adjon vissza semmit.
Morzel
- A hozzászóláshoz be kell jelentkezni
Igen ez jó megoldás lenne, de ezt a cuccot egy eszköz köpi ki magából, így ezt kell feldolgozni
- A hozzászóláshoz be kell jelentkezni
Nekem nem egészen világos amit írtál, mert a példádban nincs egyetlen ; sem...
Tehát akkor mi működik és mi nem?
Mi lehet a bemenet?
Ez az sscanf most működik?
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char *next;
if (argc <= 1)
return printf("Arg kellene...\n");
while ((next = strsep(&argv[1], ",")))
{
printf("Token: '%s'\n", next);
}
return 0;
}
fules@chaos:~$ ./tok 'egy,ketto,, negy , ot'
Token: 'egy'
Token: 'ketto'
Token: ''
Token: ' negy '
Token: ' ot'
- A hozzászóláshoz be kell jelentkezni
Ezzel annyi gond lehet, hogy nem ANSI-C, mert abban nincs strsep...
Sőt pl MinGW alatt sincs...
Helyette van strtok, de az sajnos lenyeli az üres stringet...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Ha nincs strsep, akkor ír magának egyet a polgár:
char *strsep(char **src, const char *separator) { const char *sp; char *tok; char *begin; if (!*src || !**src) return NULL; begin = tok = *src; while (*begin) { for (sp = separator; *sp; sp++) { if (*sp == *begin) { *begin++ = 0; *src = begin; return (tok); } } begin++; } *miben = NULL; return (tok); }
- A hozzászóláshoz be kell jelentkezni
Ahogy mondja, kolléga, csak nálam vmiért nem jött be a hup az imént :(.
#include <stdio.h>
const char *strchr(const char *s, int c)
{
if (!s)
return NULL;
while (*s && (*s != c))
s++;
return *s ? s : NULL;
}
char *strsep(char **s, const char *delim)
{
char *q;
if (!s || !*s || !delim || !*delim)
return NULL;
q = *s;
while (**s && !strchr(delim, **s))
(*s)++;
if (**s)
*((*s)++) = '\0';
else
*s = NULL;
return q;
}
int main(int argc, char **argv)
{
char *next;
if (argc <= 1)
return printf("Arg kellene...\n");
while ((next = strsep(&argv[1], ",")))
printf("Token: '%s'\n", next);
return 0;
}
- A hozzászóláshoz be kell jelentkezni
Az eredeti is olyan, hogy átírja a bemenetet?
Egyébként ha már magánk kell írni, akkor ez ágyúval verébre szerintem. Adott feladatra egyszerűbben is meg lehet oldani...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Át. Mind az strsep, mind az strtok. De sajnos kell is nekik, különben lehetne malloc()-kal foglalgatni meg felszabadítgatni, ráadásul menet közben, és a régi oskola szerint a rendszer/program egy stabil, kezelhető állapotot akkor hagyjon el, ha minden erőforrás a kezében van, amivel elér a köv. stabil, kezelhető állapotba, így nem lesznek olyan hibák, amikkel nem tudunk mit kezdeni. És, ha már nosztalgiázok, a malloc() igencsak drága műveletnek számít, persze nem az xmlNewDocNode()-hoz képest :).
Amágy inkább érzem ágyúval verébre lövésnek a külső lib-re való függést, ezt inkább nevezném a gatyamadzag méretre vágásának :).
- A hozzászóláshoz be kell jelentkezni
Világos...
Bár nekem szinpatikusabb megoldás lett volna egy "char *dst" argumentum mint pl strncpy-nál.
Igaz akkor meg strnsep, meg strntok kellett volna.
Ekkor nem is kell malloc, csak str(n)cpy.
Na sebaj, ez van, ezt kell szeretni. :)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
strsep()et nemigazan illik hasznalni. man 3 strsep, BUGS section
- A hozzászóláshoz be kell jelentkezni
Ezek szerint nem csak nekem szúrta a szemem, hogy módosítja a kapott stringet. Bár ez nem bug ha rendesen le van írva a leírásban.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Ilyen esetben, ket mod van:
1. atalakitod a kikopott file-t pl. sed-el olyan formara, ami "szigoru" es akkor problema nelkul tudsz egy sscanf-el dolgozni.
technikailag akar ugy is lehet, hogy a feldologozo program elott van egy script, ami csinal egy temp file-t a config-bol, s arra hivja meg a programodat (wrapper)
2. kenytelen vagy szetszedni a scanf-t, mivel itt nem tudsz olyan hivatkozast adni, mint regex-nel, hogy ha nincs akkor is jo... ;-)
Tehat a elemi lepesekre kell szedni. Ha string-bol dolgozol akkor %n-t kell hasznalni...
if(sscanf(data,"%[0-9]%*[,]%n%1c", v1,n,c) != 2)
{
error();
}
if (c == ',')
{
a_kovetkezo_ures(-:-)
}
else if(sscanf(data += n ,"%[0-9]%*[,]%n%1c", v1,n,c) != 2)
{
error();
}
if (c == ',')
{
a_kovetkezo_ures(-:-)
}
...
Persze mindezt szet lehet szedni rutinokra...
Zsiraf
- A hozzászóláshoz be kell jelentkezni
Ha már szétszedjük, szedjük szét rendesen. :)
#include <string.h>
int main ()
{
char data[]="00,123,HHU,,0181";
unsigned int i=0,j=0;
char temp[10];
while (data[ i ])
{
if (data[ i ]==',')
{
strncpy(temp,data+j,i-j);
temp[i-j]=0;
j=i+1;
// Csinalj temppel amit akarsz
}
++i;
}
return 0;
}
Tudom, mutatókkal C-sebb lenne, de nem akartam senkit lefárasztani...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Szerintem érdemes megnézni:
- A hozzászóláshoz be kell jelentkezni
Csak ajánlani tudom, én is ezt használtam pár hónapja.
- A hozzászóláshoz be kell jelentkezni
Tudnám javasolni a környezeti változókat, mint olyat :).
Ha nem fáj, hogy a programod config file-ja egyben indító script is (mint pl. az init scriptek némelyike), akkor:
VAR0="izebigyo"
VAR1="hozearmando"
/usr/local/bin/progineve
Valamint a progiban:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *p;
p = getenv("VAR0");
printf("VAR0 = '%s'\n", p ? p : "null");
p = getenv("VAR1");
printf("VAR1 = '%s'\n", p ? p : "null");
p = getenv("PATH");
printf("PATH = '%s'\n", p ? p : "null");
p = getenv("USER");
printf("USER = '%s'\n", p ? p : "null");
return 0;
}
A kulcsmozzanat: man getenv
- A hozzászóláshoz be kell jelentkezni
sscanf helyett akanlom a strchr es meg par str fuggveny hasznalatat, mert akkor tuti azt dolgozod fel amit akarsz nem pedig valamit visszakapsz alapon muxik. Ezt csak azert irom, mert eloszor en is sscanf-el probalkoztam ilyenre, de szivtam is vele. Amugy tgt-ben van meg jo config feldolgozo.
- A hozzászóláshoz be kell jelentkezni