Subjekat-predikat-objekat

Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>

Napisati program koji od zadatih reči sastavlja rečenice. Podaci su zadati u ulaznoj datoteci u sledećem formatu:

  • rec (jedna reč, do 20 karaktera)

  • vrsta (jedna reč, do 8 karaktera)

Učitati reči u jednostruko spregnutu listu, gde se novi čvorovi dodaju na kraj liste.

Od zadatih reči, formirati sve moguće rečenice u obliku subjekat-predikat-objekat. Obratiti pažnju da predikat i objekat moraju biti ispisani malim slovom, kao i da na kraju rečenice treba da stoji tačka. Prebrojati sve subjekte, predikate i objekte i na standardni izlaz ispisati koliko je ukupno moguće formirati rečenica u formatu:

Od <broj-subjekata> subjekta, <broj-predikata> predikata i <broj-objekata> objekta moguce je sastaviti <ukupan-broj-recenica> recenica.

Program se poziva sa imenom ulazne i izlazne datoteke kao vrednostima argumenata komandne linije.

U slučaju uspešnog izvršavanja programa, izaći sa status kodom 0 (EXIT_SUCCESS). Ukoliko program ne može da se izvrši do kraja usled sledećih nedostataka, izaći iz programa sa sledećim status kodovima:

  • U slučaju nedovoljnog ili suvišnog broj argumenata komandne linije, izaći iz programa sa status kodom 1 (EXIT_FAILURE)

  • U slučaju nemogućnosti dinamičkog zauzimanja memorije, izaći iz programa sa status kodom 2

  • Ako program ne može da otvori ulaznu datoteku, izaći sa status kodom 3

  • Ako program ne može da otvori izlaznu datoteku, izaći sa status kodom 4

Program realizovati tako da sve funkcije koje imaju veze isključivo sa listom (inicijalizacija, dodavanje, brisanje...) budu odvojene u jedan par datoteka koje predstavljaju zaglavlje i implementaciju.

Primer poziva programa:

./a.out reci.txt recenice.txt

Primer ulazne datoteke reci.txt:

Covek    subjekat
Tamburu  objekat
Svira    predikat
Krava    subjekat
Muze     predikat
Mesecinu objekat
Mleko    objekat

Primer rada programa:

Od 2 subjekta, 2 predikata i 3 objekta moguce je sastaviti 12 recenica.

Primer izlazne datoteke recenice.txt:

Covek svira tamburu.
Covek svira mesecinu.
Covek svira mleko.
Covek muze tamburu.
Covek muze mesecinu.
Covek muze mleko.
Krava svira tamburu.
Krava svira mesecinu.
Krava svira mleko.
Krava muze tamburu.
Krava muze mesecinu.
Krava muze mleko.

Primer rešenja

  1#include <stdio.h>
  2#include <string.h>
  3#include <ctype.h>
  4#include <stdlib.h>
  5#include "lista.h"
  6
  7#define MAX_NAZIV_IZLAZNE 11
  8
  9FILE *safe_fopen(char *, char *, int);
 10void ucitaj_reci(FILE *, REC **);
 11void ispisi_recenice(FILE *, REC *);
 12int prebroj_vrstu(REC *, char *);
 13
 14int main(int argc, char **argv)
 15{
 16    REC *glava;
 17
 18    if(argc != 3)
 19    {
 20        printf("Primer poziva programa: %s reci.txt recenice.txt\n", argv[0]);
 21        exit(EXIT_FAILURE);
 22    }
 23
 24    inicijalizacija(&glava);
 25
 26    FILE *ulazna = safe_fopen(argv[1], "r", 3);
 27    ucitaj_reci(ulazna, &glava);
 28    fclose(ulazna);
 29
 30    FILE *izlazna = safe_fopen(argv[2], "w", 4);
 31    ispisi_recenice(izlazna, glava);
 32    fclose(izlazna);
 33
 34    int broj_subjekata = prebroj_vrstu(glava, "subjekat");
 35    int broj_predikata = prebroj_vrstu(glava, "predikat");
 36    int broj_objekata = prebroj_vrstu(glava, "objekat");
 37
 38    printf("Od %d subjekta, %d predikata i %d objekta moguce je sastaviti %d recenica.\n",
 39        broj_subjekata, broj_predikata, broj_objekata, broj_subjekata * broj_predikata * broj_objekata);
 40
 41    obrisi_listu(&glava);
 42
 43    return EXIT_SUCCESS;
 44}
 45
 46FILE *safe_fopen(char *naziv, char *rezim, int kod_greske)
 47{
 48    FILE *fp = fopen(naziv, rezim);
 49
 50    if(fp == NULL)
 51    {
 52        printf("Datoteka %s nije uspesno otvorena!\n", naziv);
 53        exit(kod_greske);
 54    }
 55
 56    return fp;
 57}
 58
 59void ucitaj_reci(FILE *ulazna, REC **pglava)
 60{
 61    char tmp_rec[MAX_REC];
 62    char tmp_vrsta[MAX_VRSTA];
 63    REC *novi;
 64
 65    while(fscanf(ulazna, "%s %s", tmp_rec, tmp_vrsta) != EOF)
 66    {
 67        novi = napravi_cvor(tmp_rec, tmp_vrsta);
 68        dodaj_na_kraj(pglava, novi);
 69    }
 70}
 71
 72void ispisi_recenice(FILE *izlazna, REC *glava)
 73{
 74    REC *tekuci_subjekat = glava;
 75    REC *tekuci_predikat;
 76    REC *tekuci_objekat;
 77    char subjekat[MAX_REC];
 78    char predikat[MAX_REC];
 79    char objekat[MAX_REC];
 80
 81    while(tekuci_subjekat != NULL)
 82    {
 83        if(strcmp(tekuci_subjekat->vrsta, "subjekat") == 0)
 84        {
 85            tekuci_predikat = glava;
 86            
 87            while(tekuci_predikat != NULL)
 88            {
 89                if(strcmp(tekuci_predikat->vrsta, "predikat") == 0)
 90                {
 91                    tekuci_objekat = glava;
 92                    
 93                    while(tekuci_objekat != NULL)
 94                    {
 95                        if(strcmp(tekuci_objekat->vrsta, "objekat") == 0)
 96                        {
 97                            strcpy(subjekat, tekuci_subjekat->rec);
 98                            strcpy(predikat, tekuci_predikat->rec);
 99                            strcpy(objekat, tekuci_objekat->rec);
100                            predikat[0] += 32;
101                            objekat[0] += 32;
102                            fprintf(izlazna, "%s %s %s.\n", subjekat, predikat, objekat);
103                        }
104                        
105                        tekuci_objekat = tekuci_objekat->sledeci;
106                    }
107                }
108
109                tekuci_predikat = tekuci_predikat->sledeci;
110            }
111        }
112
113        tekuci_subjekat = tekuci_subjekat->sledeci;
114    }
115}
116
117
118int prebroj_vrstu(REC *glava, char *vrsta)
119{
120    REC *tekuci = glava;
121    int broj = 0;
122
123    while(tekuci != NULL)
124    {
125        if(strcmp(tekuci->vrsta, vrsta) == 0)
126        {
127            broj++;
128        }
129
130        tekuci = tekuci->sledeci;
131    }
132
133    return broj;
134}