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

 ( dessantos | 2013. november 17., vasárnap - 1:27 )

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á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ő.

valaki esetleg?

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....

cat < egykifile >> masikfile

Ez a masikfiléhez hozzáfűzi az egyikfilét.

> Sol omnibus lucet.

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?

ezt benéztem:)

Mivel a jelek szerint sem a ciklusokkal, sem az fread() függvénnyel nem vagy barátságban, amíg ezeket át nem nézed, lebeszélnélek a C erőltetéséről. Amit csinálni szeretnél, megoldható cmd-ben copyval, átirányítással és a set /p formulával.

> 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?

köszönet mindenkinek