C kezdő - két fájl tartalmának összehasonlítása

 ( mihaly8712 | 2017. augusztus 8., kedd - 18:55 )

Sziasztok!

Jelenleg még csak ismerkedem a nyelvvel, ezért kéretik nem megkövezni.

Van két fájlom (egyik json struktúrában, másik sima txt) amit szeretnék összevetni. Pontosabban a sima.txt fájlban lévő szavakon kellene végig iterálni (ez tényleg csak string, minden string új sorban kezdődik) és ezeket a szavakat megkeresni a json file-ban (én gyakorlatilag ezt is text fileként kezelem jelenleg), s azokat a sorokat kiíratni a json fájlból, amelyikben szerepel a sima.txt fájl szavai közül bármelyik.

Az egyszerűbb élet kedvéért egy példa:

1. fájl:

a
b
c
d
e

2. fájl:

e
f
g
h
i
a

Ugye itt a 2 fájlban a közös az a és az e betű, viszont az én "programom" csak egy betűt ad vissza minden esetben...


int main()
{
FILE *file1;
FILE *file2;

file1=fopen("/home/arch/test1.txt","r");
file2=fopen("/home/arch/test2.txt","r");

char *ch1;
char *ch2;
int var;
int cnt=0;

ch1=(char *) malloc(100*sizeof(char));
ch2=(char *) malloc(100*sizeof(char));
int i;

if ((file1 == NULL) || (file2 == NULL)) {
printf("\nCannot open file!\n");
exit(-1);

}
else {
while ((fgets(ch1,100,file1) != NULL) && (fgets(ch2,100,file2) != NULL)) {
for (i=0;i<100;i++){
if(strcmp(ch2,ch1) == NULL) {
printf("%c",ch2[i]);
}
}
}
}
return(0);
}

Tudtok segíteni mi lehet a gond? Egyszerűen nem jövök rá....

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

Az a gond, hogy a két fájl N. sorait hasonlítod össze darabonként százszor (tehát az első sort az első sorral, a második sort a második sorral, a harmadikat a harmadikkal _és csak azzal_ stb.)

Ehelyett: külső while ciklus, olvass egy sort a file1-ből. Belső ciklus-ban olvass egy sort a file2-ből, hasonlítsd össze - ha matchel, kiírás. A belső ciklus után (de a külső cikluson belül, persze), seekelj vissza file2-n az elejére.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Ez tul sok IO, nem? Szerintem egyszerubb lenne mindket filet beparsolni az elejen valami tombbe, majd azokat a tomboket mar akarhogy is ossze lehet hasonlitani (sorrendberendezes, aztan mar csak egyszer vegig kell menni a ket tombon, termeszetesen tombhatarokra figyelve, mert ha az egyik tomb rovidebb lett a masiknal, akkor konnyen tulcimezhetunk. Szerk: hulye vagyok, hat a legelso check egyike a tombhossz ellenorzese :) szerk2: mondjuk nem errol van szo a topicban, szoval ezt csak hozzakepzeltem.

IO mellett meg atlathatobb kodot is eredmenyez, mert a kodreszletek funkcio szerint szeparalva vannak, igy pl egy-egy fuggvenybe is ki lehet tenni oket. Nem mellesleg konnyebb debugolni, mert ami jol mukodik, azt egyszeruen csak nem olvassuk, nem foglalkozunk vele. Mig egy ilyen integralt megoldasnal fejben le kell mindig jatszani az egesz algoritmust. Ugyan memoriahasznalatban rosszabb, de nem hiszem, hogy ez jelen esetben szamitana.

Lehet nagy butaságot mondok, de a buffer maga nem egy tömb? Mármint ugyanúgy címezhető és kiolvasható minden eleme, mint egy string tömbnek.

Amúgy próbáltam ezt a megoldást, mármint a 2 fájl elemeit beolvastatni egy tömbbe és ezeket összehasonlítani, de kb ugyanez jött ki, ami a fenti probléma. Lehet hogy az egysoros while miatt van a gond, mivel ha az egyik file tartalmaz 6 sort, a másik csak 5-öt, akkor mindkét fájlból csak 5 sort fog kiolvasni. Nem értem miért.....

--

Warning! Use ANY version of Windows at your own risk!

Mert ugyanazt a logikai hibát követted el, am it már SzBlacky leírt elsőként. Érdemes lenne elolvasni. A programod jó, lefordítható, futtatható, csak nem azt csinálja, amire használni akarod.

hat igen a magikus szavak az egymasba agyazott ciklus lenne, meg a rendezesek.

Jó esetben a legelső olvasásnál bekerül a cache-be, aztán jó napot :) Aztán persze amit írtam, elég rosszul skálázódik, ez jogos, de inkább arra próbáltam rámutatni, hogy mi a legalapvetőbb gond a kódjával.

Átláthatóbb kód... én első körben nem C-nek állnék neki ennek, hanem valami olyanban, ahol vannak értelmes adatszerkezetek out-of-the-box :) pl. Javaban ez két BufferedReader és két Set, a Stream API miatt már ciklus sem kell, egy retainAll hívás és a kiíratás.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Mondjuk, ha az alapoktól kezdjük, akkor:
Fóthi Ákos - Bevezetés a programozásba: kétváltozós elemenkénti feldolgozás
(http://people.inf.elte.hu/ekonyvtar/html/ch12.html)

Legrosszabb esetben is rendezni kellene az inputot először mondjuk.

♲♻♲

cJSON + strtok()

SzBlackY: Köszönöm szépen a segítséget, ezzel az útmutatással sikerült megoldani a problémát. :)

A többieknek is köszi a tanácsot, biztos sokféle megoldás van még erre az egyszerű képletre amit aztán viszek tovább az eredeti probléma megoldásához, viszont még most tanulom a nyelvet. Python-ban úgy ahogy van már tapasztalatom, de most direkt C nyelvben akartam megvalósítani....

--

Warning! Use ANY version of Windows at your own risk!

Az egymasba agyazott ciklus azert egy nyelvfuggetlen dolog. Ezt pythonban is egymasba kellene agyazni.
Itt nem annyira a C volt a problema szerintem.
A neten megtalalhato python, c, akarmi oktato anyagokban ezeket az egyszeru algoritmusokat is atveszik. Erdemes eloszor egy ilyet vegigcsinalni, ha erdekel a programozas.

Igen, a problémát nem értette meg igazán. Azaz azt, hogy nem kódolunk ész nélkül. Kis feladatot/problémát is el lehet cseszni ezzel. Először mindig végiggondoljuk, hogy mit is fogunk csinálni, mit akarunk eredménynek, milyen utak vezetnek oda, stb. A pszeudo kód csodákra képes, esetleg a folyamatábra skiccelése is.

ehh, a regi szep idok, amikor meg papiron nyomtuk a folyamatabrakat, kicsi ovalisbol indulunk aztan teglalap, majd decision-hoz a trapez, stb, stb. Egsz nagy progikat csinaltunk benne. Volt, hogy az epiteszektol kertunk A0-st es oten rajzoltunk hangyafasznyi kis abrakat. Aztan rajottunk, hogy jobb szetszedni inkabb kis egysegekre. Szep idok voltak na. :D

Nem is baxtad el annyiszor a kódot.
Viszont a business logic refaktor kicsit macerásabb volt. :)

Ebben igazatok van, sajnos hajlamos vagyok ilyen kisebb programoknál (?? annak sem mondanám :P) beleugrani mindenféle tervezés nélkül, hogy majd jön ahogy 'aggya és finomítunk rajta menet közben.

A neten található tutorialok alapján próbáltam kicsemegézni hogy mikor merre hány méter, így utólag mondhatni sikerült is megértenem.

Próbálom rászoktatni magam a pszeudokódra és a tervezésre. Nem hiszem hogy valaha is nagy programozói babérokra fogok törni, de az alapokkal tisztában akarok lenni. Inkább az IT security miatt tanulom a nyelvet, hogy ha később arra a szintre eljutok, megértsem az exploit-okat amelyek c-ben íródtak, stb...

--

Warning! Use ANY version of Windows at your own risk!

Az a probléma, hogy kevered a "tanuljunk nyelvet" és a "találjuk ki a feladatra az algoritmust" c. dolgokat. Ez a kettő egyben nem fog menni. A nyelvet olyan feladatokon keresztül kéne tanulni, ahol egyértelmű, hogy mi az algoritmus, az algoritmus kitalálásának meg ismert nyelvvel érdemes nekiállni.

Így a kisebb feladatok 5-10x annyi ideig tartanak mire jók lesznek, mintha legalább fejben végigjátszottad volna.
Nagyba meg ne is kezdj így!

Nulladik tipp: http://pastebin.com praktikusabb forráskódok bemutatásához, könnyebb elolvasni, így könnyebb segíteni neked.

A feladatodról:
1. egyetlen alkalommal olvasd be a memóriába egy láncolt listába a szavakat, amiket keresel. Ehhez a struct kifejezést ajánlom tanulmányozni. Egyik eleme a következő struktúraelem címe, a másik eleme pedig maga a string. És persze malloc segítségével foglalhatod a következő szóhoz a struktúrát.
2. olvasd fel az adatfájl újabb sorát és a láncolt lista szavait minden alkalommal végigszaladva vesd össze strcmp() segítségével.

Illetve akármennyire is unalmas, ezt az alapművet mindenekelőtt nagyon ajánlom elolvasni: http://vili.pmmf.hu/portal/documents/18/13228/c_kernighan.pdf
Tényleg sokat segíthet neked az alapok elsajátításában.