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.cfájlból keletkezzenkomment_nelkul.cfá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 (**).)
