2 két szöveges fájl összefűzése

Fórumok

Sziasztok

köszönöm az eddigi segítségeket.
Az összefűzés sikerült, csak változott a program. Mivel a fájlnak amit összeakarok fűzni,a neve és tartalma változni fog (szöveges ps fájl), ezért abban kérem a segítségeteket, hogy egy változó sorhosszúságú fájt, hogyan tudok kiolvasni teljesen és miben tároljam, milyen típusú tömben? fgetch- el egy valamekkora hosszúságú sort ki tudok olvasni de többet már nem.
Vagy binárisan olvassam ki inkább, és az pontosabb lenne?( és azt hogy kell?:))

Előre is köszönöm.

Hozzászólások

Szia,
<off>
Az eredeti probléma megjelölése elég sokat segíthetne a jelenlegi probléma átlátásában :) Ne haragudj, de nem könnyű visszanyomozni, mi is volt az eddig sikeres megoldás, és mi volt a helyes megoldás, ahogy a bemeneti szöveges fájl specifikációja is hasznos lenne.
Nem mellékesen, a használt nyelv is sokat segíthet (Ez C/C++ topic, és a kettő közt elég széles különbségek lehetnek...).
</off>

Általánosan, ha az egyik fájlt mindenképpen végig akarod olvasni (bár, szerintem célszerűbb lenne soronként,vagy kisebb blokkonként nézni. Időigényesebb, az I/O-t terheli, de kevesebb memória hibát hordoz talán):
Ha C: Láncolt lista, mivel a sorok maximális hossza ismeretlen, egy-egy lista elembe gyűjteném egy sor tartalmát (EOL vagy EOF-ig, ha elérnénk a fájl végét időközben), mondjuk 80 karakter hosszú "c-string"-ek tömbjébe. ( Vagyis 80 karakteres tömb lenne egy-egy elem a karakter tömbben. Mindegyik _szigorúan_ 0-s karakterrel zárva, a tömb hosszúságát tárolva. Pl. az alábbi struktúrába (szintaxis hibáért sry, rég c/c++-oztam :) ):

typedef char row_block[80];
struct line_struct{
struct line_struct * next_line; //Következő sor
struct line_struct * prev_line; //Előző sor. A keresés optimalizálásra.
row_block * lines; // A sorok tömbjét dinamikusan foglalnám. Némi optimalizálási lehetőséget ad :)
int block_count; // Inkább tároljuk, hogy egy sor hány "blokkból" áll...
};

Nem optimális, de legalább általánosan fedheti a problémát.
C++ esetén hasonlóan járnék el, de a megfelelő STL osztályokat használnám, elvégre is, pont erre vannak, és C string helyett természetesen a C++-os String osztályt. Lehet, kevésbé optimális, de mégis csak jobban betesztelt megoldás, mint amit írni tudnánk kapásból :)

Üdv,
LuiseX
Szerk: Ami kimaradt: A végig olvasáshoz ezzel a megoldással egy fgetc-vel EOL vagy EOF-ig kell olvasnod. Két egymásba ágyazott ciklus kell, az egyik _csak_ EOF esetén lép ki, a másik pedig EOL vagy EOF-ig megy. A belső ciklusod tölti fel a row_block-ot, a külső pedig, line_struct-ba rakja a beolvasott row_block-ot.

Köszönöm , kicsit meredeknek tűnik főleg hogy nem vagyok programozó de így utólag leírom a problémámat.
Adott egy ps fájl, melynek az elejéhez változó szöveget kell írnom.
A változó szöveget, ami a felhasz, ad meg beleratom egy fájlba. Ez működik. Majd olvasom ezt a fájlt pontosan, minden hozzáadott karakter nélkül, kiírom majd egy ideiglenes fájlba és amit már meoldottak a többiek, egyszerűen egymés után összefűzöm. Ezt teszteltem, mükszik.
Jah és sima c- ben vagyunk:), ezt választottam ,csak azért:).
Amit írtál kicsit erős még nekem, főleg az egymásba írt ciklus,(rég volt már az suliba), de azért köszönöm.
Próbálkozok, utána olvasok....

Szia,
Ha jól sikerült értelmeznem a problémát, akkor egyszerűen az új fájl végére akarod írni az új fájl tartalmát?
Ekkor a megoldás ennél jóval egyszerűbb, és amit meditor kolléga írt, bőven megoldja a problémát.
Ha más miatt is kell, és C-ben szeretnéd, akkor egyszerűen másképp kell a bővítendő fájlt megnyitni, és automatikusan hozzá fűzi :)

FILE * target;

char filename[50];
strncpy(filename, "filenev.nev", strlen("filenev.nev"));
filename[strlen("filenev.nev")]="\0";
/* Ez a körülményes filenév érték adás igazából azért van, hogy láss egy kicsit biztonságosabb változó másolást. A "filenev.nev" string helyett nyugodtan írhatsz változót is, így tudod használni máshoz is, és amíg nem léped át a jelen esetben az 50 karakter hosszúságot bemenet terén, megbízhatónak tekinthető :)
Persze lehet, van jobb megoldás, de kezdetnek már ez is védelem a memleakek ellen...
*/

target = fopen ( filename, "a"); /*A mivel ha nem létezik a fájl, létrehozza, ha nem, a file végére ugrik, így folytathatod ott, ahol abbahagytad*/

A továbbiakban a target file-t úgy írod, ahogy eddig is írtad, a tartalom a fájl végére kerül mindenképpen :)
Igazából, ha ez volt a probléma, akkor rossz kifejezést használtál. Az összefűzés jelentésében azt hordozza, hogy valamilyen tartalmi elv szerint A fájl-t a B fájlba illeszted, a fájl eredeti sorrendjét követve. Pl. A minden sora után egy sort illesztesz be B fájlból.
Az itt használandó kifejezés a hozzáfűzés lenne szerintem, de ez fixme témakör :)
Üdv,
LuiseX

szia
Köszönöm, de kicsit szerintem elbeszélünk(még leírni sem tudom rendesen:)).
Van a felhasználó, hoz egy valamilyen nevű kész postcript fájlt,bemásolja egy könyvtárba és elindít egy exe-t Windoson.
Az bekér pár adatot. Ebből a pár adatból létrehozok egy fájlt. Eddig megvagyok.

Bekéne kérni az ő hozott fájljának a nevét,és megnyitni ezt a fájlt. Eddig is kész.
A fájlból kiolvasni a tartalmat és eltárolni egy ideiglenes fájlban, mivel ez egy ps fájl(szöveges)fontos, hogy ugyan azt tároljam el, ami benne van. EZt nem tudom.

A két fájlt összefűzni, copyval, már ez is sikerült.
Fontos, hogy a hozott fájl ELEJÉRE kerüljön a bekért adatokat tartalmazó fájl.

Na ezt szeretném elérni,

egy Tészlet, hogy milyen szinten vagyok:):)

printf("\nKérem a fájl nevét:\n");

scanf("%s",&fn);

printf("%s",fn);
fp2=fopen(fn,"rt");
fgets(d,100,fp2);
fp3=fopen("c:\\ideiglenes.ps","wt");
fwrite(&d,1,100,fp3);
fclose(fp3);

//system("copy c:\\4.ps+c:\\ideiglenes.ps c:\\végleges.ps");

Az fgetsnél van végem, mert nyílván csak sorokat olvas ki..... és nekem egész értelems szöveg kellene

Azért köszi

Szia,
Lehetséges, bár annyira nem :) Csak a fa már teljesen kitakarja azt a fránya erdőt :P
Másold át a hozott fájlt, majd a fentebb leírt módszerrel ehhez fűzd hozzá ami neked kell. Így nem kell erőlködnöd :)
Szerintem karakterenként olvasd, így nem kell tudnod előre, milyen hosszú a forrás fájlod ( ez pazarló megoldás, főleg I/O terén, de ettől tekintsünk most el ;) )
Kissé pseudó kódban írva, de a lényege a következő:

...
// input_file a hozott fájl, vegleges_file a korábbi 'vegleges.ps'
// output_file pedig a kimeneti fájl.
char c=0;
while ( c = fgetc(input_file) != EOF ){
fputs(c, output_file);
}
/*Ha nem akarsz pazarolni, ráérsz a vegleges.ps-t itt, a kettő ciklus között megnyitni*/
c=0;
while (c = fgetc(vegleges_file) != EOF){
fputs(c, output_file);
}
/*Itt pedig simán törlöd a korábbi vegleges_filet, persze miután zártál minden IO-t fclose-al,
és az output_file-t a helyére másolod :)
*/

Primitív megoldás, de legalább nem kell a memóriával vesződnöd.
Ahogy a szavaidból kiveszem, modern gépen fog futni, nem valami cél hw-en, így igazából megengedheted magadnak azt a luxust szerintem, hogy kicsit IO pazarló megoldást alkalmazz, illetve a program célja sem tűnik túl komplexnek.
De ha csak ennyiből áll a célprogram, a helyedben szimplán scriptelném, a fentebbi logikának megfelelően :)
Üdv,
LuiseX

köszönöm, ezt kerestem, de amit nem értek az még mindig az, hogy :

while ( c = fgetc(input_file) != EOF ){
fputs(c, output_file);

az fgetc et hogyan paraméterezem fel? mert írod, fgetc(input_file) !=EOF
ez azt jelenti? hogy a fájl végéig olvastatod?
a zárójelbe ilyen kor elég csak a fájl név????

Tudom valszeg triviális dolgot kérdezek, de nekem ez a rész nem világos "csak"...

Köszönöm, üdv

Szia,
fgetc egy karaktert olvas a paraméterként beadott fájlból, és visszaadja az értékét.
A fenti kontextusban c = fgetc(input_file) != EOF jelentése az alábbi: c kapja meg az fgetc értékét, majd ezt hasonlítsa össze az EOF karakterrel. (EOF == End of file).
Bár , belegondolva nem vagyok biztos az operátor precedenciába, így inkább (c = fgetc(input_file)) != EOF) formát javasolnám. C-vel aktuálisan dolgozó kollégák biztos tudnak korrigálni ez ügyben :)
De sajnos osztanom kell lx kolléga véleményét. Amennyiben fontos a feladat, és csak ennyi szükséges, akkor inkább keress olyan alternatívát ami jobban kézre áll :)
Ha csak tanulni szeretnéd a nyelvet, először ajánlom egy C-vel foglalkozó könyv áttanulmányozását az ott fellépő példákat végig követve.
Üdv,
LuiseX

szia

Még annyit írj meg légyszi,
fp2=fopen(fn,"rt");
while ((c=fgetc(fn)) != EOF)
itt nekem az fn az egy 10 elemes char tömb amibe a hozott fájl nevet raktam kértem be, a felhsználótól.
a megnyitásra nem dob hibát, magyarul megtalálja a filet, persze a program abban a könyvtárban van ahol a fájlt rakják majd.

viszont a a wile os sor nem megy át, az a baja, hogy az fn az egy változó????

előre is köszi

Az fopen() függvénynek megadtad a fájl nevét, és hogy milyen módon nyitod meg, és kaptál tőle egy FILE pointert, vagy handlert, vagy -kezelőt, ahogy elnevezni tetszik.
Jön a rávezető keresztkérdés: a fájlból olvasó, abba író vagy abban mozgó függvények paraméterként a fájlnevet várnák, vagy ezt a FILE pointert, amit a fájl megnyitásakor kaptunk?

> Be kéne kérni az ő hozott fájljának a nevét,és megnyitni ezt a fájlt. Eddig is kész.
A fájlból kiolvasni a tartalmat és eltárolni egy ideiglenes fájlban, mivel ez egy ps fájl(szöveges)fontos, hogy ugyan azt tároljam el, ami benne van. Ezt nem tudom.

Teljesen mindegy, hogy szöveges vagy szövegtelen-e a fájl, mindig fontos, hogy a másolat azonos legyen az eredetivel. Van rá kész módszer (cat, COPY etc), de ha hobbyból kézileg akarod, akkor pl: fopen+fread+fwrite+fclose (a fopen-nél fontos a "b"=binary opció) az egyik lehetőség.

Az még mindig nem világos, hogy ha két fájlból akarsz egy harmadikat létrehozni, akkor miért kell először másolatot csinálni az egyik inputról... Talán vallási okból?