Fájl megváltoztatása

 ( Anonymous | 2004. február 13., péntek - 9:13 )

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Hello mindenkinek!

Van egy nagyon egyszerû kérdésem, nem vagyok még nagymenõ a C-ben:

Szeretnék egy olyan funkciót írni, ami beolvas egy fájlt, megkeres benne bizonyos stringeket és ezeket kicseréli valami másra.

Tudom, hogy ezt meg lehet csinálni egy bufferrel amibe fread-el beolvasom az egész fájlt, aztán úgy kezelem mint egy stringet. Regexp-el keresek, a cserére meg írni kell valamit.

Ezzel az a baj, hogy nagyobb fájlokban vagy ha keresett szövegrész hosszú és sokszor fordul elõ, elég lassú lehet.

Az fputs, frwrite, fputc stb. parancsokkal direkt módon írhatok a stream-be, viszont ezek fölülírják az adatokat adott pozición, ha a csere szöveg hosszabb mint a cserélni kívánt cucc.

Az lenne a kérdésem, hogy nincs-e erre más mód? Jó lenne a beolvasott buffert csak keresésre használni és a megfelelõ részeket a poziciók alapján kicserélni a fájlban.

Köszönöm!

Sziasztok

1. open régi file

2. create tempfile

3. mindenféle keresés

4. találatig kiírás a tempbe

5. új szöveg kiírása tempbe

6. folytatás 3.-tól amíg file vége

...

7. tempfile átnevezése régi file-vé

Amúgy ha darabonként keresel, akkor a probléma az átlapolások hathatós kezelése... :-(

Zsiráf

OK köszi szépen!

Ok

kipróbáltam és tök jó, viszont most a keresésekkel van gond.

Egy szót vagy kifejezést szeretnék megkeresni, ami akár x helyen is szereplhet a fájlban.

A gondom a következõ:

Mind a PCRE regexp és a C lib beépített funkciói használnak egy tömböt, amibe elhelyezik a találatok elje / vége poziciókat. De sajnos ez ugye subexpression találatokra van kitalálva...-:( Az elsõ találat annak a stringnek a pozíciója, amely teljes egészében megfelelt a keresett mintának. A többi elvileg azoké amelyek csak részben feleltek meg.

De mi a helyzet akkor ha minden "subexpression" megfelel a teljes kifejezésnek?
A C libje ezt nem kezeli rendesen (valamelyik man page szerint), a PCRE kicsit más, de az eredmény ugyanaz.

Sajnos csak az elsõ pozicióját jegyzik fel, a többit pedig vagy meg se találják vagy minden pos azonos lesz.

Hogy lehetne ezt megoldani? Vagy ehhez nem is regexpet kéne használni, inkább maradjak az strstr és társainál? Attól tartok az nagyobb fájlok és sok keresés esetén jelentõsen lassíthat..

Ebben kérnék segítéset!

Köszi elõre!

Sziasztok

Bill

Izé, lehet, hogy valami nem világos előtted :-)

A subexpression, nem azt jelenti, hogy részben felelt meg a mintának :-) hmm

nézzük a következő regexpet:

([a-z]+)[0-9a-z]*\.([0-9a-z]{0,3})

itt van egy regexp, ami vagy illeszkedik, vagy nem a stringedre! Nincs részben illeszkedés, azzal nem foglalkozik senki. Talált, vagy nem!!!

Viszon van benne 2 [b:37b2f81738]subexpression[/b:37b2f81738] a két zárójeles () rész. Namost a tömböd 0 eleme azt adja meg, hogy a sztingedben mettől-meddig tart az egész regexp, az 1. eleme ugyanezt az első zárójeles részre, a második eleme a második zárójeles részre ... :-)

Zsiráf

Köszi a választ. Jó rendben akkor ezt félreértettem kissé -:). Nekem akkor nem ez kell, de akkor most hogyan találhatom meg többször ugyanazt POSIX / PCRE regexpel?

A kifejezés csak egy szó, pl "provider" vagy ilyemsi.

Ha ezt simán keresem, akkor a pcre_exec csak egy találatot eredményez, holott 3 helyen is szerepel a fájlban. Ez ezek szerint így ok, hisz így subexpression nincs, tehát nem is tölti ki a tömböt.

De akkor most mivel lehetne megkeresni a többi pozicióját?

Az iHTML nyelvbõl indultam ki. Ott bármilyen kifejezést megtalál akárhányszor és a poziciók mennek egy listába. Ez lett volna jó C-ben is..-:)

[quote:2d44313339="Anonymous"]A kifejezés csak egy szó, pl "provider" vagy ilyemsi.
[/quote:2d44313339]

Ha csak egy fix stringre keresel, akkor nem erdemes regexpet hasznalnod. Egy egyszeru strstr() megoldja a problemadat:

[code:1:2d44313339]char *buf; // ez amiben keresel
char *kincs; // ez az amit keresel

char *talalat; // ez mutatja a talalat helyet
while( (talalat=strstr(buf, kincs)) ) {
// kiirod a buf-tol talalatig terjedo reszt,
// kiirod a csere stringet
buf = talalat + strlen(kincs);
}
[/code:1:2d44313339]
Ennyi.

Koszi szepen

Azota mar kitalaltam egy modszert PCRE-vel is, de ez sokkal egyszerubb.

Koszonom mindenkinek a segitseget.