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
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
6#define MAX_REC 21
7#define MAX_VRSTA 9
8
9#define MAX_NAZIV_IZLAZNE 11
10
11typedef struct rec_st
12{
13 char rec[MAX_REC];
14 char vrsta[MAX_VRSTA];
15 struct rec_st *sledeci;
16} REC;
17
18FILE *safe_fopen(char *, char *, int);
19void ucitaj_reci(FILE *, REC **);
20void ispisi_recenice(FILE *, REC *);
21
22void inicijalizacija(REC **);
23REC *napravi_cvor(char *, char *);
24void dodaj_na_kraj(REC **, REC *);
25int prebroj_vrstu(REC *, char *);
26void obrisi_listu(REC **);
27
28int main(int argc, char **argv)
29{
30 REC *glava;
31
32 if(argc != 3)
33 {
34 printf("Primer poziva programa: %s reci.txt recenice.txt\n", argv[0]);
35 exit(EXIT_FAILURE);
36 }
37
38 inicijalizacija(&glava);
39
40 FILE *ulazna = safe_fopen(argv[1], "r", 3);
41 ucitaj_reci(ulazna, &glava);
42 fclose(ulazna);
43
44 FILE *izlazna = safe_fopen(argv[2], "w", 4);
45 ispisi_recenice(izlazna, glava);
46 fclose(izlazna);
47
48 int broj_subjekata = prebroj_vrstu(glava, "subjekat");
49 int broj_predikata = prebroj_vrstu(glava, "predikat");
50 int broj_objekata = prebroj_vrstu(glava, "objekat");
51
52 printf("Od %d subjekta, %d predikata i %d objekta moguce je sastaviti %d recenica.\n",
53 broj_subjekata, broj_predikata, broj_objekata, broj_subjekata * broj_predikata * broj_objekata);
54
55 obrisi_listu(&glava);
56
57 return EXIT_SUCCESS;
58}
59
60FILE *safe_fopen(char *naziv, char *rezim, int kod_greske)
61{
62 FILE *fp = fopen(naziv, rezim);
63
64 if(fp == NULL)
65 {
66 printf("Datoteka %s nije uspesno otvorena!\n", naziv);
67 exit(kod_greske);
68 }
69
70 return fp;
71}
72
73void ucitaj_reci(FILE *ulazna, REC **pglava)
74{
75 char tmp_rec[MAX_REC];
76 char tmp_vrsta[MAX_VRSTA];
77 REC *novi;
78
79 while(fscanf(ulazna, "%s %s", tmp_rec, tmp_vrsta) != EOF)
80 {
81 novi = napravi_cvor(tmp_rec, tmp_vrsta);
82 dodaj_na_kraj(pglava, novi);
83 }
84}
85
86void ispisi_recenice(FILE *izlazna, REC *glava)
87{
88 REC *tekuci_subjekat = glava;
89 REC *tekuci_predikat;
90 REC *tekuci_objekat;
91 char subjekat[MAX_REC];
92 char predikat[MAX_REC];
93 char objekat[MAX_REC];
94
95 while(tekuci_subjekat != NULL)
96 {
97 if(strcmp(tekuci_subjekat->vrsta, "subjekat") == 0)
98 {
99 tekuci_predikat = glava;
100
101 while(tekuci_predikat != NULL)
102 {
103 if(strcmp(tekuci_predikat->vrsta, "predikat") == 0)
104 {
105 tekuci_objekat = glava;
106
107 while(tekuci_objekat != NULL)
108 {
109 if(strcmp(tekuci_objekat->vrsta, "objekat") == 0)
110 {
111 strcpy(subjekat, tekuci_subjekat->rec);
112 strcpy(predikat, tekuci_predikat->rec);
113 strcpy(objekat, tekuci_objekat->rec);
114 predikat[0] += 32;
115 objekat[0] += 32;
116 fprintf(izlazna, "%s %s %s.\n", subjekat, predikat, objekat);
117 }
118
119 tekuci_objekat = tekuci_objekat->sledeci;
120 }
121 }
122
123 tekuci_predikat = tekuci_predikat->sledeci;
124 }
125 }
126
127 tekuci_subjekat = tekuci_subjekat->sledeci;
128 }
129}
130
131void inicijalizacija(REC **pglava)
132{
133 *pglava = NULL;
134}
135
136REC *napravi_cvor(char *rec, char *vrsta)
137{
138 REC *novi = (REC *)malloc(sizeof(REC));
139
140 if(novi == NULL)
141 {
142 printf("Greska prilikom zauzimanja memorije!\n");
143 exit(2);
144 }
145
146 strcpy(novi->rec, rec);
147 strcpy(novi->vrsta, vrsta);
148 novi->sledeci = NULL;
149
150 return novi;
151}
152
153void dodaj_na_kraj(REC **pglava, REC *novi)
154{
155 if(*pglava == NULL)
156 {
157 *pglava = novi;
158 }
159 else
160 {
161 REC *tekuci = *pglava;
162
163 while(tekuci->sledeci != NULL)
164 {
165 tekuci = tekuci->sledeci;
166 }
167
168 tekuci->sledeci = novi;
169 }
170}
171
172int prebroj_vrstu(REC *glava, char *vrsta)
173{
174 REC *tekuci = glava;
175 int broj = 0;
176
177 while(tekuci != NULL)
178 {
179 if(strcmp(tekuci->vrsta, vrsta) == 0)
180 {
181 broj++;
182 }
183
184 tekuci = tekuci->sledeci;
185 }
186
187 return broj;
188}
189
190void obrisi_listu(REC **pglava)
191{
192 REC *tmp;
193
194 while(*pglava != NULL)
195 {
196 tmp = *pglava;
197 *pglava = (*pglava)->sledeci;
198 tmp->sledeci = NULL;
199 free(tmp);
200 }
201}