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
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
Napomene¶
Zbog učitavanja jednog karaktera, format string u
fscanf
naredbi 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 sabreak
naredbom
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}