Segítséget szeretnék kérni, hogyan lehet C-ben egy iso8859-2 kódolású txt fájl sorait beolvasni, ha nem tudom előre egy sor hosszát? Nem akarok egy nagy buffert lefoglalni, van -e arra mód, hogy megtudjam a beolvasandó sor hosszát, hogy dinamikusan tudjam a buffer méretet ehhez állítani? Vagy van erre valami más, szebb módszer?
- 5597 megtekintés
Hozzászólások
Foglalsz neki valamekkora helyet malloc()-kal, ha mar a vege fele jarsz, akkor foglalsz meg hozza realloc()-kal.
- A hozzászóláshoz be kell jelentkezni
Lehet, hogy butaságot írok, de mintha az fgets
elvárná, hogy maximalizáld a beolvasandó sor hosszát. Ergó akkor már nyugodtan lehet ekkora puffert is foglalni. Arról nem is beszélve, hogy szerintem a soronkénti alloc / realloc nem kicsit lassítja a dolgot.
- A hozzászóláshoz be kell jelentkezni
keresem a legfrankóbb módszert erre. sok helyen láttam azt, hogy lefoglalnak mondjuk egy 4 vagy 8KB-s buffert és abba olvasnak, vagy egy tömbbe, de nem lehet ezt úgy, hogy annyit foglalni le amekkora a beolvasandó sor? utána felszabadítani, majd allokálni megint amekkora a következő. szóval jó ez a lefoglalok előre egy buffert, de mi van ha extrém hosszú egy sor?
- A hozzászóláshoz be kell jelentkezni
Ha extrém hosszú a sor, akkor szívás van.
A legegyszerűbb (dinamikus) megoldás: van egy puffered amibe ált befér egy sor (mondjuk 1024), egyszerre ennyit olvasol a fájlból. Keresel benne sorvége jelet - amíg van, visszaadod addig és a másik pufferben lévő maradékot. Ha nincs, vagy maradt, azt hozzáadod a másik (maradvány) pufferedhez - ennek a méretét realloc-al állítod kellő méretűre.
Bonyolult, neked kell csinálni a sorvége keresést és kezelést.
Egyszerűbb az fgets, oszt ha elszáll, akkor allokálsz kétszer akkora puffert, és újra próbálkozol.
- A hozzászóláshoz be kell jelentkezni
Extrém hosszú sorokat nem fogja beolvasni az fgets()
. Hiszen meg kell adni neki, mennyit olvasson be maximum, ha ennél hosszabb egy sor, akkor azt két (vagy több) sornak fogja venni (ha jól emlékszem). Szerintem nem véletlenül használják ezt a módszert (x kb puffer, aztán hajrá...)
Vagy valami mással próbálsz beolvastatni?
Vagy várható, hogy extrémen hosszú sorok lesznek?
- A hozzászóláshoz be kell jelentkezni
igazából én speciel az fscanf -re gondoltam ugyanis azzal lehet sort beolvasni, hiszen megadható olyan minta amire ráillik a sztring\n vagyis a "%s\n" és így pon egy sort fog beolvasni, ami nekem ideális lenne.. főleg ha tudnám, hogy ez összesen hány bájt mert akkor a beolvasás előtt le tudnám allokálni :-)
és mivel ez ilyen beadandó feladat lesz, így nyilván valóan az extrém dolgokat fogják vizsgálni, hogy mennyire tűri azok kezelését.. gondolom én.
- A hozzászóláshoz be kell jelentkezni
Szerintem ilyenre a realloc()-os megoldas marad, teny, hogy eroforrasigenyes.
- A hozzászóláshoz be kell jelentkezni
Ha egy viszonylag nagy kezdeti bufferrel hasznalod a reallocos megoldast, akkor a realloc majdnem sose hivodik meg (gyakorlatilag par plusz branch lesz a kododban), es kezelted az extrem eseteket is. Nem 2 byte helyet kell foglalni, es azt novelni exponencialisan.
- A hozzászóláshoz be kell jelentkezni
> de nem lehet ezt úgy, hogy annyit foglalni le amekkora a beolvasandó sor?
Könyörgöm, érted a saját kérdésedet? Lehet, ha tudod, hogy milyen hosszú a sor. De nem tudod. Akkor most hogyan?
- A hozzászóláshoz be kell jelentkezni
szeretem az ilyen épületes hozzászólásokat :-D
- A hozzászóláshoz be kell jelentkezni
Szeretem az ilyen épületes kérdéseket :-D
Tudtommal C-re kérdeztél, de feltételezted, hogy mint a Pascalban, tárolódik a sztring hossza. De nem. Innentől olyat nem tudsz, hogy ha tudom a hosszát, annyi memóriát foglalok le.
Tessék lefoglalni valamennyit, abba beolvasni (ha akarod fgets-sel, ha akarod fread-del, ha akarod mással). Ha olyan eszközt használsz, amelyik ellenőrzi helyetted a sorvéget jó, ha nem olyat, tedd meg. Ha volt sorvég megvagy, ha nem volt, újabb memóriafoglalás, újabb olvasás.
- A hozzászóláshoz be kell jelentkezni
fura ez a getline nagyon frankón működik, és még allokálnom se kell megoldja maga.
- A hozzászóláshoz be kell jelentkezni
getline?
- A hozzászóláshoz be kell jelentkezni
Ezt nem ismertem, de ez is reallocot hasznal, es at kell neki adni a mallocolt helyet, szoval csak a sorvege nezest csinalja meg helyetted.
- A hozzászóláshoz be kell jelentkezni
végigolvastad a manját? ha a ptr NULL-ba mutat, akkor allokol neked!
- A hozzászóláshoz be kell jelentkezni
Nem, es tenyleg.
- A hozzászóláshoz be kell jelentkezni
ez jól hangzik :-) köszi!
- A hozzászóláshoz be kell jelentkezni
nm.
- A hozzászóláshoz be kell jelentkezni
És ez milyen könyvtár része?
$ man getline
No manual entry for getline
FreeBSD 6.2beta2
- A hozzászóláshoz be kell jelentkezni
CONFORMING TO
Both getline() and getdelim() are GNU extensions. They are
available since libc 4.6.27.
- A hozzászóláshoz be kell jelentkezni
mmap(). Ez virtuálisan az egészet berántja a memóriába, nem is kell allokálni semmit, ráadásul ha egyszerre több processz is így tesz a fájllal, akkor géped memóriájában csak egyszer lesz benne, nem annyiszor ahány processz beolvasta.
- A hozzászóláshoz be kell jelentkezni
De csak korrekt len paraméterrel. És esetleg tessen tesztelni különböző oprendszerek között portábilitás szempontjából. (És itt most nem arra gondoltam, hogy UHU vs SUSE.)
- A hozzászóláshoz be kell jelentkezni
Ja igen, kifelejtettem: megnyitod, majd fstat() rá, megvan a mérete, ekkor jöhet az mmap. Hátrány hogy csak igazi fájlokra működik, stream-re nem.
- A hozzászóláshoz be kell jelentkezni
Nem kellene egy iskolai feladatból csodákat kihozni... kb ilyesmi:
char linebuff [4096];
int len, leave;
long lineno;
for (leave= 0, lineno= 0; ! leave && fgets linebuff, sizeof (linebuff), f) != NULL;) {
++lineno;
len = strlen (linebuff);
if (len==0 || linebuff[len-1] != '\n') {
fprintf (stderr, "Line %ld: too long or contains 0x00\n", lineno);
leave = 1;
} else {
/* do something */
}
}
- A hozzászóláshoz be kell jelentkezni
Amúgy meg természetesen mindenkinek köszönöm a hozzászólást, nem akarnék ölre menő vitát kirobbantani, mert annyira tényleg nem bonyolult, csupán felötlött bennem a kérdés, hogy a sok megoldási lehetőség közül melyik az amit a legjobban lehetne használni erre. nekem speciel ez a getline nagyon bejön, elolvastam a manuálját, megnéztem a példát ami a man-ban van és nagyon szuperül működik is. természetesen ugyanolyan jól működik az összes többi változat is. A program ami ezt használná pedig egy iso8859-2 --> repülő ékezet ; repülő ékezet --> iso8859-2 -es konverter lenne. Az input lehet rendes ékezetes vagy repülő ékezetes egy fájlba sorokra bontva, melyből egy másik fájlba kell elkészíteni a konverziós párját, mint kimeneti fájl.
- A hozzászóláshoz be kell jelentkezni
És egy ilyen progihoz miért kell sorokat olvasni? A newline mennyiben más, mint egy szóköz vagy egyéb írásjel? Simán jó lett volna, hogy olvasol mondjuk 1024 byte-ot, vagy akár csak 1-et getchar()-ral, feldolgozod, kiírod, esetleg amikor repülőből kódolsz vissza, akkor a végén maradhat 1 karakter amit még nem tudsz feldolgozni, azt viszed "tovább", olvasol hozzá még... Mondjuk ha én számtech tanár lennék, nagyon-nagyon csúnyán néznék arra, aki egy triviális véges automatát úgy kódol le, hogy tetszőlegesen nagyra nőhet a memóriaigénye.
- A hozzászóláshoz be kell jelentkezni
nem kell sorokat olvasni, de lehet. Az feladatban még a sorok hosszát is maximalizálták 80 karakterben, pusztán kíváncsiságból kérdeztem meg. az előre lefoglalt bufferbe olvasás és annak feldolgozása tökéletesen jó, meg a karakterek egyesével beolvasása is, bár a buffer szerintem jobb. de láss csodát létezik egy sor olvasó függvény is, méghozzá teljesen klasszul.
- A hozzászóláshoz be kell jelentkezni
>> CONFORMING TO
Both getline() and getdelim() are GNU extensions. They are
available since libc 4.6.27.
Ugye ezt is elolvastad? Magyarul baromi sok ertelme van megtanulni, leven egy kb. egyedul Linuxon mukodo megoldas. Eljen a platformfuggetlen C-programozas. Grrr.
- A hozzászóláshoz be kell jelentkezni