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}