Dešifruj broj telefona¶
Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>
Brojevi telefona zajedno sa uslugama i imenima pružaoca usluga kojoj pripadaju predstavljeni su u strukturi na sledeći način:
ime pružaoca usluge (jedna reč, maksimalno 20 karaktera)
usluga (jedna reč, maksimalno 10 karaktera)
broj telefona (jedna reč, maksimalno 20 karaktera)
Brojevi telefona zadati su korišćenjem slova zarad lakšeg pamćenja, što je tehnika koja se često koristi u SAD. Evropljanin, kome ovaj princip nije poznat bi želeo da nazove brojeve sa spiska za određenu uslugu koja mu je u datom trenutku potrebna. Učitati brojeve telefona iz ulazne datoteke u jednostruko spregnutu listu (novi elementi dodaju se na kraj liste), zatim uraditi sledeće:
Na osnovu imena usluge koja se zadaje kao argument komandne linije u izlaznu datoteku ispisati imena pružaoca zajedno sa dešifrovanim brojem telefona u formatu %-12s %s
.
Izlaznu datoteku nazvati telefoni-<usluga>.txt
, gde <usluga>
predstavlja ime zadate usluge (pogledati primer izlazne datoteke).
Brojevi telefona dešifruju se na osnovu tabele:
Slova |
Brojevi |
---|---|
ABC |
2 |
DEF |
3 |
GHI |
4 |
JKL |
5 |
MNO |
6 |
PQRS |
7 |
TUV |
8 |
WXYZ |
9 |
Primer ulazne datoteke imenik.txt
:
BurgerKing hrana 1-877-BURGERS
BestCars prodaja 1-440-NO1CARS
DominosPizza hrana 1-800-2APIZZA
SleepWell prodaja 1-336-79NIGHT
KFC hrana 1-762-CHICKFC
Wallmart prodaja 1-289-HITWALL
McDonalds hrana 1-865-DONALDS
Primer poziva programa:
./desifruj_brojeve imenik.txt hrana
Primer izlazne datoteke telefoni-hrana.txt
:
BurgerKing 1-877-2874377
DominosPizza 1-800-2274992
KFC 1-762-2442532
McDonalds 1-865-3662537
Primer rešenja¶
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#define MAX_IME_PRUZAOCA 21
6#define MAX_USLUGA 11
7#define MAX_BROJ_TELEFONA 21
8
9#define MAX_IME_IZL_DAT (13 + MAX_USLUGA) // strlen("telefoni_") + MAX_USLUGA + strlen(".txt")
10
11typedef struct imenik_st {
12 char ime_pruzaoca[MAX_IME_PRUZAOCA];
13 char usluga[MAX_USLUGA];
14 char broj_telefona[MAX_BROJ_TELEFONA];
15 struct imenik_st *sledeci;
16} IMENIK;
17
18FILE *safe_fopen(char *, char *, int);
19void ucitaj_u_imenik(FILE *, IMENIK **);
20void ispisi_po_tipu_usluge(FILE *, IMENIK *, char *);
21
22void inicijalizacija(IMENIK **);
23IMENIK *napravi_cvor(char *, char *, char *);
24void dodaj_na_kraj(IMENIK **, IMENIK *);
25void konvertuj_brojeve_telefona(IMENIK *);
26void obrisi_listu(IMENIK **);
27
28void desifruj_broj_telefona(char *);
29
30int main(int argc, char **argv) {
31 IMENIK *glava;
32
33 if(argc != 3) {
34 printf("Primer poziva: %s imenik.txt hrana\n", argv[0]);
35 exit(EXIT_FAILURE);
36 }
37
38 inicijalizacija(&glava);
39
40 FILE *ulazna = safe_fopen(argv[1], "r", 3);
41 ucitaj_u_imenik(ulazna, &glava);
42 fclose(ulazna);
43
44 konvertuj_brojeve_telefona(glava);
45
46 char ime_izl_dat[MAX_IME_IZL_DAT];
47 sprintf(ime_izl_dat, "telefoni-%s.txt", argv[2]);
48 FILE *izlazna = safe_fopen(ime_izl_dat, "w", 4);
49 ispisi_po_tipu_usluge(izlazna, glava, argv[2]);
50 fclose(izlazna);
51
52 obrisi_listu(&glava);
53
54 return EXIT_SUCCESS;
55}
56
57FILE *safe_fopen(char *name, char *mode, int error_code) {
58 FILE *fp = fopen(name, mode);
59
60 if(fp == NULL) {
61 printf("Nije moguce otvoriti fajl %s!\n", name);
62 exit(error_code);
63 }
64
65 return fp;
66}
67
68void ucitaj_u_imenik(FILE *ulazna, IMENIK **pglava) {
69 char tmp_ime_pruzaoca[MAX_IME_PRUZAOCA];
70 char tmp_usluga[MAX_USLUGA];
71 char tmp_broj_telefona[MAX_BROJ_TELEFONA];
72
73 while(fscanf(ulazna, "%s %s %s",
74 tmp_ime_pruzaoca,
75 tmp_usluga,
76 tmp_broj_telefona
77 ) != EOF) {
78 IMENIK *novi = napravi_cvor(tmp_ime_pruzaoca, tmp_usluga, tmp_broj_telefona);
79 dodaj_na_kraj(pglava, novi);
80 }
81}
82
83void ispisi_po_tipu_usluge(FILE *izlazna, IMENIK *glava, char *usluga) {
84 IMENIK *tekuci = glava;
85
86 while(tekuci != NULL) {
87 if(strcmp(tekuci->usluga, usluga) == 0) {
88 fprintf(izlazna, "%-12s %s\n", tekuci->ime_pruzaoca, tekuci->broj_telefona);
89 }
90
91 tekuci = tekuci->sledeci;
92 }
93}
94
95void inicijalizacija(IMENIK **pglava) {
96 *pglava = NULL;
97}
98
99IMENIK *napravi_cvor(char *ime_pruzaoca, char *usluga, char *broj_telefona) {
100 IMENIK *novi = (IMENIK *) malloc(sizeof(IMENIK));
101
102 if(novi == NULL) {
103 printf("Greska prilikom zauzimanja memorije!\n");
104 exit(2);
105 }
106
107 strcpy(novi->ime_pruzaoca, ime_pruzaoca);
108 strcpy(novi->usluga, usluga);
109 strcpy(novi->broj_telefona, broj_telefona);
110
111 novi->sledeci = NULL;
112
113 return novi;
114}
115
116void dodaj_na_kraj(IMENIK **pglava, IMENIK *novi) {
117 if(*pglava == NULL) {
118 *pglava = novi;
119 } else {
120 IMENIK *tekuci = *pglava;
121
122 while(tekuci->sledeci != NULL) {
123 tekuci = tekuci->sledeci;
124 }
125
126 tekuci->sledeci = novi;
127 }
128}
129
130void konvertuj_brojeve_telefona(IMENIK *glava) {
131 IMENIK *tekuci = glava;
132
133 while(tekuci != NULL) {
134 desifruj_broj_telefona(tekuci->broj_telefona);
135 tekuci = tekuci->sledeci;
136 }
137}
138
139void obrisi_listu(IMENIK **pglava) {
140 IMENIK *tmp;
141
142 while(*pglava != NULL) {
143 tmp = *pglava;
144 *pglava = (*pglava)->sledeci;
145 tmp->sledeci = NULL;
146 free(tmp);
147 }
148}
149
150void desifruj_broj_telefona(char *broj_telefona) {
151 int i;
152
153 for(i = 0; i < strlen(broj_telefona); i++) {
154 switch(broj_telefona[i]) {
155 case 'A': case 'B': case 'C':
156 broj_telefona[i] = '2';
157 break;
158 case 'D': case 'E': case 'F':
159 broj_telefona[i] = '3';
160 break;
161 case 'G': case 'H': case 'I':
162 broj_telefona[i] = '4';
163 break;
164 case 'J': case 'K': case 'L':
165 broj_telefona[i] = '5';
166 break;
167 case 'M': case 'N': case 'O':
168 broj_telefona[i] = '6';
169 break;
170 case 'P': case 'Q': case 'R': case 'S':
171 broj_telefona[i] = '7';
172 break;
173 case 'T': case 'U': case 'V':
174 broj_telefona[i] = '8';
175 break;
176 case 'W': case 'X': case 'Y': case 'Z':
177 broj_telefona[i] = '9';
178 break;
179 }
180 }
181}