Stajalište za gradski autobus

Autor zadatka: Rade Radišić <radisic.rade@uns.ac.rs>

Napisati program koji nalazi sve željene autobuske linije koje staju na stajalištu nakon zadatog vremena. Podaci su zadati u ulaznoj datoteci u sledećem formatu:

  • naziv_linije (jedna reč, do 50 karaktera)

  • broj_linije (celobrojna vrednost)

  • vreme_dolaska (jedna reč, do 4 karaktera)

Učitati linije u statički niz, zatim u izlaznu datoteku ispisati samo one linije koje pripadaju zadatim linijama nakon određenog vremena. Ime ulazne i izlazne datoteke, kao i vreme se zadaju kao argument komandne linije, dok se željene linije zadaju putem standardnog ulaza. Korisnik programa unosi tražene linije dokle god ne unese vrednost -1, što označava kraj korisničkog unosa (pogledati primer rada programa). U izlaznu datoteku ispisati broj linije i vreme dolaska.

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

  • Zarad jednostavnosti, prilikom unosa, pretpostaviti da se jedna linija ne moze izabrati vise puta

  • Sprovesti odgovarajuću validaciju korisničkog unosa (dozvoljene vrednosti su od 1 do 15 i -1)

Primer poziva programa:

./a.out linije.txt trazene-linije.txt 1800

Primer ulazne datoteke linije.txt:

KLISA-CENTAR-LIMAN_I 1 1804
LIMAN_IV-CENTAR-Z._STANICA 4 1810
PODBARA-CENTAR-ADICE 6 1802
NOVO_NASELJE-CENTAR-LIMAN_I 8 1803
PETROVARADIN-CENTAR-DETELINARA 3 1801
KLISA-CENTAR-LIMAN_I 1 1747
LIMAN_IV-CENTAR-Z._STANICA 4 1732

Primer rada programa:

Uneti brojeve od 1 do 15 ili -1 za izlazak:
Linija: 1
Linija: 4
Linija: 8
Linija: -45
Ne postoji zadata linija!
Linija: -1

Primer izlazne datoteke trazene-linije.txt:

1 1804
4 1810
8 1803

Primer rešenja

 1#include <stdio.h>
 2#include <string.h>
 3#include <stdlib.h>
 4
 5#define MAX_NAZIV_LINIJE 51
 6#define MAX_VREME_DOLASKA 5
 7
 8#define MAX_SIZE 30
 9
10typedef struct linija_st
11{
12    char naziv_linije[MAX_NAZIV_LINIJE];
13    int broj_linije;
14    char vreme_dolaska[MAX_VREME_DOLASKA];
15} LINIJA;
16
17FILE *safe_fopen(char *, char *, int);
18void ucitaj_linije(FILE *, LINIJA *, int *);
19void ispis_trazene_linije(FILE *, LINIJA *, int, char *, int);
20
21int main(int argc, char **argv)
22{
23    LINIJA linije[MAX_SIZE];
24    int n;
25
26    if(argc != 4)
27    {
28        printf("Primer poziva: %s linije.txt trazene-linije.txt 1800\n", argv[0]);
29        exit(2);
30    }
31
32    FILE *ulazna = safe_fopen(argv[1], "r", 3);
33    ucitaj_linije(ulazna, linije, &n);
34    fclose(ulazna);
35
36    int trazena_linija;
37    FILE *izlazna = safe_fopen(argv[2], "w", 4);
38
39    // Zarad jednostavnosti, prilikom unosa, pretpostaviti da se jedna linija ne moze izabrati vise puta
40    printf("Uneti brojeve od 1 do 15 ili -1 za izlazak:\n");
41    do
42    {
43        printf("Linija: ");
44        scanf("%d", &trazena_linija);
45        if(trazena_linija < -1 || trazena_linija == 0 || trazena_linija > 15)
46        {
47            printf("Ne postoji zadata linija!\n");
48        }
49        else if(trazena_linija != -1)
50        {
51            ispis_trazene_linije(izlazna, linije, n, argv[3], trazena_linija);
52        }
53    } while(trazena_linija != -1);
54
55    fclose(izlazna);
56
57    return 0;
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_linije(FILE *ulazna, LINIJA *linije, int *pn)
74{
75    int i = 0;
76
77    while(fscanf(ulazna, "%s %d %s", 
78            linije[i].naziv_linije, &linije[i].broj_linije, linije[i].vreme_dolaska) != EOF)
79    {
80        i++;
81    }
82
83    *pn = i;
84}
85
86void ispis_trazene_linije(FILE *izlazna, LINIJA *linije, int n, char *vreme, int trazena_linija)
87{
88    int i, nadjena_linija;
89
90    for(i = 0;i < n;i++)
91    {
92        if(linije[i].broj_linije == trazena_linija && strcmp(vreme, linije[i].vreme_dolaska) < 0)
93        {
94            fprintf(izlazna, "%d %s\n", linije[i].broj_linije, linije[i].vreme_dolaska);
95        }
96    }
97}