SOS¶
Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>
Napisati program koji dekodira poruke napisane pomoću Morzeove abecede. Podaci su zadati u ulaznoj datoteci u sledećem formatu:
slovo (jedan karakter)
kod (jedna reč, do 5 karaktera)
Učitati Morzeove kodove u statički niz, na osnovu kojih će se u izlaznu datoteku ispisati dekodirane reči.
Ime ulazne i izlazne datoteke se zadaju kao argument komandne linije, dok se reči napisane u Morzeovoj azbuci zadaju preko standardnog ulaza.
Korisnik programa unosi reči čija su pojedinačni kodovi slova razdvojeni jednim razmakom dokle god ne unese string kraj, što označava kraj korisničkog unosa (pogledati primer rada programa).
Ukoliko je unet Morzeov kod koji nije definisan u ulaznoj datoteci, umesto slova napisati upitnik ?.
Pretpostaviti da će korisnik isključivo unositi karaktere -, . i string kraj, stoga nije potrebno raditi dodatnu validaciju unosa.
Izlazna datoteka sadrži originalnu reč napisanu pomoću Morzeove azbuke, strelicu -> i prevedenu reč.
Format je %s -> %s.
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
2Ako program ne može da otvori ulaznu datoteku, izaći sa status kodom
3Ako program ne može da otvori izlaznu datoteku, izaći sa status kodom
4
Napomene¶
Zbog učitavanja jednog karaktera, format string u
fscanfnaredbi mora sadržati znak za novi red"%c %s\n"Beskonačna petlja u programskom jeziku C se može napisati kao
while(1), dok se iz nje se može izaći sabreaknaredbom
Primer poziva programa:
./a.out kodovi.txt poruka.txt
Primer ulazne datoteke kodovi.txt:
A .-
E .
I ..
O ---
U ..-
P .--.
S ...
T -
Primer rada programa:
Uneti kodirane reci (za prestanak, ukucati rec kraj):
... --- ...
- .- ...
.--. .- ...
-- --- ...
kraj
Primer izlazne datoteke poruka.txt:
... --- ... -> SOS
- .- ... -> TAS
.--. .- ... -> PAS
-- --- ... -> ?OS
Primer rešenja¶
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4
5#define MAX_KOD 5
6
7#define MAX_SIZE 30
8
9#define MAX_KODNA_REC 51
10#define MAX_REC 51
11
12typedef struct morzeov_kod_st
13{
14 char slovo;
15 char kod[MAX_KOD];
16} MORZEOV_KOD;
17
18FILE *safe_fopen(char *ime, char *rezim, int kod_greske);
19void ucitaj_kodove(FILE *ulazna, MORZEOV_KOD *MORZEOV_KODovi, int *pn);
20void dekodiraj_rec(MORZEOV_KOD *MORZEOV_KODovi, int n, char *MORZEOV_KODna_rec, int duzina_MORZEOV_KODne_reci, char *rec);
21
22int main(int argc, char **argv)
23{
24 MORZEOV_KOD kodovi[MAX_SIZE];
25 int n;
26
27 if(argc != 3)
28 {
29 printf("Primer poziva: %s kodovi.txt poruka.txt\n", argv[0]);
30 exit(2);
31 }
32
33 FILE *ulazna = safe_fopen(argv[1], "r", 3);
34 ucitaj_kodove(ulazna, kodovi, &n);
35 fclose(ulazna);
36
37 char kodna_rec[MAX_KODNA_REC] = "";
38 char rec[MAX_REC];
39
40 // ... --- ... SOS
41 // - .- ... TAS
42 // .--. .- ... PAS
43 // -- --- ... MAS
44
45 FILE *izlazna = safe_fopen(argv[2], "w", 4);
46 printf("Uneti kodirane reci (za prestanak, ukucati rec kraj):\n");
47 while(1)
48 {
49 fgets(kodna_rec, MAX_KODNA_REC, stdin);
50 int duzina = strlen(kodna_rec);
51 if(kodna_rec[duzina - 1] == '\n')
52 {
53 kodna_rec[--duzina] = '\0';
54 }
55
56 if(strcmp(kodna_rec, "kraj") == 0)
57 {
58 break;
59 }
60
61 dekodiraj_rec(kodovi, n, kodna_rec, duzina, rec);
62 fprintf(izlazna, "%s -> %s\n", kodna_rec, rec);
63 }
64 fclose(izlazna);
65
66 return 0;
67}
68
69FILE *safe_fopen(char *naziv, char *rezim, int kod_greske)
70{
71 FILE *fp = fopen(naziv, rezim);
72
73 if(fp == NULL)
74 {
75 printf("Datoteka %s nije uspesno otvorena!\n", naziv);
76 exit(kod_greske);
77 }
78
79 return fp;
80}
81
82void ucitaj_kodove(FILE *ulazna, MORZEOV_KOD *kodovi, int *pn)
83{
84 int i = 0;
85
86 while(fscanf(ulazna, "%c %s\n",
87 &kodovi[i].slovo, kodovi[i].kod) != EOF)
88 {
89 i++;
90 }
91
92 *pn = i;
93}
94
95void dekodiraj_rec(MORZEOV_KOD *kodovi, int n, char *kodna_rec, int duzina_kodne_reci, char *rec)
96{
97 int i, j, duzina_reci = 0, duzina_kodiranog_slova = 0, nadjen_kod = 0;
98 char kodirano_slovo[MAX_KOD] = "";
99
100 for(i = 0;i < duzina_kodne_reci;i++)
101 {
102 if(kodna_rec[i] == ' ' || i == duzina_kodne_reci - 1)
103 {
104 if(i == duzina_kodne_reci - 1)
105 {
106 kodirano_slovo[duzina_kodiranog_slova++] = kodna_rec[i];
107 }
108
109 kodirano_slovo[duzina_kodiranog_slova++] = '\0';
110 for(j = 0;j < n;j++)
111 {
112 if(strcmp(kodirano_slovo, kodovi[j].kod) == 0)
113 {
114 rec[duzina_reci++] = kodovi[j].slovo;
115 nadjen_kod = 1;
116 break;
117 }
118 }
119
120 if(!nadjen_kod)
121 {
122 rec[duzina_reci++] = '?';
123 }
124
125 duzina_kodiranog_slova = 0;
126 }
127 else
128 {
129 kodirano_slovo[duzina_kodiranog_slova++] = kodna_rec[i];
130 }
131 }
132
133 rec[duzina_reci++] = '\0';
134}