Utolsó módosítás: 2009. március 19.
Gyakorlaton megnéztük, hogy lehet egy szövegben megkeresni egy bizonyos szövegrészletet.
Az h6g0.c program lényegében ez a gyakorlaton vizsgált program.
Ha lefordítja a programot a gcc -Wall -O -o h6g0 h6g0.c
paranccsal,
majd lefuttatja a ./h6g0 < h5g0be0
paranccsal, ahol a
h5g0be0 szöveges fájl Arany János Tetemre hívás című
versét tartalmazza, akkor ezt a kimenetet kapjuk.
Ki *se terítteti, meg se mosatja: "Lélek ez ajtón *se be, se ki..." Legyen a *seb vérzése tanú. Déli verőn *sem süt oda nap; Hiába! nem indul *sebe a holtnak Erre *se vérzik Bárczi fia. Megkönnyezetlen *senki se hagyja, Nem fakad a *seb könnyre megint. Mindre nem érez *semmit a holt: Könnye *se perdűl, jajja se hallik, Tanum az Ég, s minden *seregi! S vadul a *sebből a tőrt kiragadja, S vérc*se-visongással rohan el. Vetni kezet rá *senki se mer. Táncolni, dalolni *se szégyell;
A program tehát csak azokat a sorokat írja ki, amikben szerepel a "se" sztring, és megjelöli ennek az első előfordulását egy csillaggal.
A program legérdekesebb része az a sor volt, ahol egy függvénynek egy tömb valamelyik belső elemére mutatót adtunk át argumentumként, de a függvény erről nem tud semmit.
40 putstring(line + pos, len - pos);
Ugyanezt lehet felhasználni arra, hogy egy találat után a változatlan search függvénnyel megkeressük a következő előfordulását is a "se" sztringnek a beolvasott sorban. Gyakorlásként érdemes lehet megpróbálkoznia megírni ezt a változatot is, ami egy sorban több találatot is megtalál, tehát a kimenet a következő. (Ha nincs kedve, akkor csalhat is úgy, hogy megnézi a már megírt programot, de akkor legalább találja meg rá a linket a gyakorlati anyagok oldalról.)
Ki *se terítteti, meg *se mosatja: "Lélek ez ajtón *se be, *se ki..." Legyen a *seb vérzé*se tanú. Déli verőn *sem süt oda nap; Hiába! nem indul *sebe a holtnak Erre *se vérzik Bárczi fia. Megkönnyezetlen *senki *se hagyja, Nem fakad a *seb könnyre megint. Mindre nem érez *semmit a holt: Könnye *se perdűl, jajja *se hallik, Tanum az Ég, s minden *seregi! S vadul a *sebből a tőrt kiragadja, S vérc*se-visongással rohan el. Vetni kezet rá *senki *se mer. Táncolni, dalolni *se szégyell;
A soronként több találatnak azonban nincs sok köze a mostani házi feladathoz, amiben ugyanis a kereső programot más irányban kell továbbfejlesztenie.
Írjon ugyanis egy olyan programot, ami nem csak a "se" sztringre, hanem tetszőleges sztringre tud keresni a standard bemenet soraiban. A program a sztringet parancssori argumentumként kell, hogy megkapja. A sztring hossza is tetszőleges lehet. Továbbra is csak soronként az első találatot jelezze csillaggal, és azokat a sorokat, ahol nincs találat, ne írja ki.
Ha tehán a futtatható program neve h6g6, akkor a
./h6g6 se < h5g0be0
parancs eredménye ugyanaz kell, hogy legyen,
mint korábban a ./h6g0 < h5g0be0
parancsé.
További példák. A ./h6g6 Bárc < h5g0be0
eredménye
Halva találták *Bárczi Benőt. "Hát ki?..." riad fel *Bárczi sötéten, Erre se vérzik *Bárczi fia. Jöjjön elő *Bárc, a falu, mind!" "*Bárczi Benőt én meg nem öltem
A ./h6g6 "l a" < h5g0be0
eredménye pedig
Kastélyába vitette fö*l atyja, Ál*l a tetemnél tiszti pörosztó, Állva fejéné*l az, vagy emez: Vádda*l az önnön szívemig ér: Csak odakap, hol fészke*l az agy: Döbbenet álta*l a szív ere fagy: S vadu*l a sebből a tőrt kiragadja,
(az idézőjel arra kell, hogy a shell a szóközt tartalmazó három karakteres sztringet egy argumentumként adja át a programnak, ne pedig két külön argumentumként.)
A parancssori argumentumokat az operációs rendszer és a C futtatási környezet indításkor bemásolja a program memóriájába, és mutatókon keresztül teszi elérhetővé. Ahhoz, hogy ezt használjuk a main függvényt úgy kell definiálni, hogy két paramétere legyen a következő módon.
int main(int argc, char **argv)
Az első paraméter (hagyományosan argc a neve) eggyel nagyobb, mint ahány parancssori argumentummal van meghívva a program, tehát ebben a példában 2 (érdemes ezt ellenőrizni is a programban). A második paraméter (argv) egy char * típusú elemekből álló tömbre mutat, amely argc elemből áll, és minden eleme egy parancssori argumentumhoz tartozik. Minden ilyen elem egy karaktertömbre mutat, ezek mindegyike 0 értékű karakterrel van lezárva. A 0 karakteren kívül máshonnan nem derül ki, milyen hosszúak az egyes argumentumok. Az argv[0] nem argumentumra mutat, hanem a program nevére, ezt általában nem szoktuk elérni, az argv[1] mutat az első argumentumra, stb, az argv[argc-1] az utolsóra. Minden program, például a gcc vagy a cat is ezeken a mutatókon keresztül éri el a parancssori argumentumokat.
A programot érdemes a h6g0.c egy másolatának módosításával előállítani, de akár teljesen új programot is kezdhet, ha azt könnyebbnek találja.
A megoldást e-mailben küldje el az címre. Az emailben csatolmányként küldje el a megoldáshoz használt forráskódot, és írhat bármilyen megjegyzéseket, amit a megoldással kapcsolatban lényegesnek talál. Az emailben feltétlenül adja meg a nevét, nem szeretnék névtelen házi feladatokat azonosítani. Írja továbbá az emailbe az "info2" szöveget, valamint a feladat rövid nevét, jelen esetben azt, hogy "keresés", hogy könnyebben szét tudjam válogatni a feladatokat. (Ez utóbbi új szabály, korábban nem gondoltam rá, hogy a házi feladatokat meg is kéne különböztetni egymástól.)
Ha a feladathoz bármilyen kérdése van, vagy elakad a megoldással, akkor keressen meg emailben vagy személyesen, akár a gyakorlaton, akár azon kívül.
A feladatot 2009. március 19-én illetve 20-án tűzom ki. A megoldás határideje ehhez képest két hét, vagyis április 3. péntek (aznap még be lehet küldeni).