1 Kommentszűrő
Írj programot, amely a szabványos bemenetről olvas karaktereket fájl vége jelig! A szabványos bemeneten keresztül egy C program érkezik. A program szűrje ki a /* és */ közötti megjegyzéseket a szabványos bemeneten érkező szövegből, és a megjegyzések nélküli szöveget írja a szabványos kimenetre!
- Tervezz állapotgépes modellt a feladat megoldására! Készíts
állapottáblát és tevékenységtáblát, valamint állapotgráfot! A
hallgatók önálló próbálkozása után csoport beszélje meg a
megoldást a laborvezetővel!
Tipp: ha nem megy, nézd meg a 6. heti előadás diáit, az állapotgéphez kapcsolódó részt! A kommentszűrőnek négy állapota lesz: alap, csillagra vár a '/' után, megjegyzésben van, '/'-re vár a '*' után.
- A terv alapján írd meg a feladatot megoldó C nyelvű programot! Próbáld ki billentyűzetről!
- Mentsd el úgy a programodat, hogy vannak benne /* megjegyzések */ is. Nyiss egy parancssori
ablakot, és keresd meg benne a futtathatót (.exe)! Irányítsd át a szabványos bemenetet
a második laboron tanult módon
úgy, hogy a programod a saját maga forráskódját kapja bemenetként! Ellenőrizd, hogy
helyesen eltűnnek-e belőle a megjegyzések! Próbáld ki az átirányítást fájlból fájlba is:
a
main.c
fájlból keletkezzenkomment_nelkul.c
fájl!
Megoldás
#include <stdio.h> int main() { typedef enum Allapot { alap,per,komm,csill } Allapot; int c; /* Beolvasott karakter */ Allapot all = alap; /* Alapállapotról indulunk */ while ((c=getchar())!=EOF) { /* Fájl végéig olvasunk */ switch (all) { case alap: /* Ha alapállapotban vagyunk */ if (c=='/') all=per; /* Jött egy per, lehet komment lesz ezért nem írjuk ki */ else putchar(c); /* Egyébként kiírjuk ami jött */ break; case per: /* Már jött egy perjel */ if (c=='*') all=komm; /* Ha csillag jön, kommentben vagyunk */ else if (c=='/') putchar('/'); /* Ha mégegy perjel jött, * akkor az előzőt kiírjuk, * és maradunk ebben az állapotban */ else { /* Ha valami más jött, akkor kiírjuk * az előző perjelet, az aktuális karaktert */ putchar('/'); /* és visszamegyünk alapállapotba */ putchar(c); all=alap; } break; case komm: /* Ha kommentben vagyunk */ if (c=='*') all=csill; /* Csillagot figyeljük és nem írunk ki semmit */ break; case csill: /* Ha jött egy csillag a kommentben */ if (c=='/') all=alap; /* Perjel esetén vége a kommentnek -> Alapállapot */ else if (c=='*') all=csill; /* Csillag esetén nincs teendő */ else all=komm; /* Egyéb esetben visszamegyünk a komment állapotba */ break; } } /* Ha véget ért a bemenet, elvileg alapállapotban kell lennünk, mert * a forráskód nem végződhet bezáratlan kommenttel. Esetleg lehetséges, * hogy egy perjel volt a végén, az viszont nem a komment vége, hanem * egy osztás: írjuk ki! */ if (all==per) putchar('/'); return 0; }
2 A kommentek aránya
Azt mondják, egy szépen megírt program forráskódjának 30%-a megjegyzés. (A missziókritikus programokban, pl. a NASA űrhajót irányító programjában ez sokkal több lehet!) Módosítsd úgy a programodat, hogy a forráskód beolvasása közben meghatározza ezt az arányt is! A kiírás tevékenységek így kiegészülnek a számlálással is.
A most megírt programod hány százaléka komment?
Tipp: tedd el magadnak a most megírt programot. Jól fog jönni a nagy házi feladatod kódja minőségének számszerűsítéséhez. ☺
3 Sztringes feladatok
Lapozz vissza az előző labor feladataira, a 7. héthez. Oldd meg azokat a sztringes feladatokat, amelyekre a múlt órán nem volt idő!
4 További feladatok
Sztringek belseje I.
A négy állapotos C kommentszűrő program nem működik tökéletesen. Ugyanis ez a kód nem tartalmaz kommentet:
printf("/* ez nem komment. */\n");
Javítsd ki úgy az állapotgéped, hogy kezelje ezt is!
Sztringek belseje II.
Hol van vége egy sztringnek? Nem az indító idézőjel utáni következő idézőjel karakternél:
printf("A program azt irja ki, hogy \"Hello, /* nem komment */ vilag\".\n");
Fejleszd tovább az állapotgépet eszerint!
Szöveges fájlok
Írd át a kommentszűró programot úgy, hogy parancssori paraméterként vegye át a forrás- és célfájl nevét! Nyissa meg a fájlokat szöveges módban, és fájlkezelő függvényekkel olvassa és írja a bemenetet és kimenetet! A munka végén ne felejtsd bezárni a fájlokat! A kommentektől megszabadított forráskód a kimeneti fájlba, a kommentek statisztikáját (komment karakterek, összes karakterek, százalék) pedig a szabványos kimenetre írja a program!
A szabványos bemenetről olvasó, kimenetre író
getchar()
ésputchar()
függvényeknek van fájlos párja is: ezek nevefgetc()
ésfputc()
.A main függvény paraméterei pedig:
int main(int argc, char **argv)
.
Multifilter
Írd át a kommentszűró programot úgy, hogy ne csak a /*
és */
karakterpárokra működjön, hanem tetszőleges karakterpárokra! Pl.
a Pascal nyelvben a kommenteket (*
és *)
karakterekkel is lehetett
jelölni. A kezdő- és végpárokat a felhasználó egy konfigurációs
fájlban (multifilter.ini) adhassa meg a programnak!
A program ellenőrizze, hogy létezik-e a fájl, és ha
nem, adjon hibajelzést, majd lépjen ki! (Ha sikerült megnyitnia
a fájlt, abban négy karakternek kell lennie; a nyitó kombinációnak,
két karakter, és a záró kombinációnak, újabb két karakter. C-hez
a fájlban /**/
lenne, Pascalhoz (**)
.)