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}
1#ifndef LISTA_H
2#define LISTA_H
3
4#define MAX_REC 21
5#define MAX_VRSTA 9
6
7typedef struct rec_st
8{
9 char rec[MAX_REC];
10 char vrsta[MAX_VRSTA];
11 struct rec_st *sledeci;
12} REC;
13
14void inicijalizacija(REC **);
15REC *napravi_cvor(char *, char *);
16void dodaj_na_kraj(REC **, REC *);
17void obrisi_listu(REC **);
18
19#endif
1#include <stdio.h>
2#include <string.h>
3#include <ctype.h>
4#include <stdlib.h>
5#include "lista.h"
6
7void inicijalizacija(REC **pglava)
8{
9 *pglava = NULL;
10}
11
12REC *napravi_cvor(char *rec, char *vrsta)
13{
14 REC *novi = (REC *)malloc(sizeof(REC));
15
16 if(novi == NULL)
17 {
18 printf("Greska prilikom zauzimanja memorije!\n");
19 exit(2);
20 }
21
22 strcpy(novi->rec, rec);
23 strcpy(novi->vrsta, vrsta);
24 novi->sledeci = NULL;
25
26 return novi;
27}
28
29void dodaj_na_kraj(REC **pglava, REC *novi)
30{
31 if(*pglava == NULL)
32 {
33 *pglava = novi;
34 }
35 else
36 {
37 REC *tekuci = *pglava;
38
39 while(tekuci->sledeci != NULL)
40 {
41 tekuci = tekuci->sledeci;
42 }
43
44 tekuci->sledeci = novi;
45 }
46}
47
48void obrisi_listu(REC **pglava)
49{
50 REC *tmp;
51
52 while(*pglava != NULL)
53 {
54 tmp = *pglava;
55 *pglava = (*pglava)->sledeci;
56 tmp->sledeci = NULL;
57 free(tmp);
58 }
59}
1.PHONY: clean
2a.out: lista.o resenje.o
3 gcc lista.o resenje.o
4resenje.o: resenje.c
5 gcc -c resenje.c
6lista.o: lista.c
7 gcc -c lista.c
8clean:
9 rm *.o a.out