Prijemni ispit

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

Kandidati za upis na fakultet predstavljeni su u strukturi na sledeći način:

  • ime kandidata(jedna reč, maksimalno 20 karaktera)

  • prezime kandidata (jedna reč, maksimalno 30 karaktera)

  • ostvareni broj bodova na prijemnom ispitu (neoznačen broj)

Kandidati su radili prijemni ispit i ostvarili određen rezultat. Potrebno je "podvući crtu", odnosno, odrediti broj kandidata koji su prošli prijemni ispit. Učitati kandidate iz ulazne datoteke u jednostruko spregnutu listu (novi elementi dodaju se tako da lista bude sortirana po ostvarenim bodovima u opadajućem redosledu), zatim uraditi sledeće:

Na osnovu broja primljenih kandidata koji se zadaju kao argument komandne linije u izlaznu datoteku ispisati redni broj, ime, prezime i ostvareni broj bodova kandidata u formatu %2u %-7s %-7s %2u. Podvući crtu ispod poslednjeg primljenog kandidata, crta se sastoji od 30 crtica (karakter -). Naziv ulazne i izlazne datoteke su zadati redom, kao prvi i drugi argument komandne linije.

Primer ulazne datoteke kandidati.txt:

Mika   Milacic 67
Milana Matic   55
Petar  Pavlov  85
Bojana Beric   92
Aleksa Katic   45
Goran  Jelic   73
Stefan Dakic   95
Marina Medic   86

Primer poziva programa:

./lista_kandidata kandidati.txt preliminarna-lista.txt 5

Primer izlazne datoteke preliminarna-lista.txt:

 1. Stefan  Dakic   95
 2. Bojana  Beric   92
 3. Marina  Medic   86
 4. Petar   Pavlov  85
 5. Goran   Jelic   73
------------------------------
 6. Mika    Milacic 67
 7. Milana  Matic   55
 8. Aleksa  Katic   45

Primer rešenja

  1#include <stdio.h>
  2#include <string.h>
  3#include <stdlib.h>
  4
  5#define MAX_IME 21
  6#define MAX_PREZIME 31
  7
  8typedef struct kandidati_st {
  9    char ime[MAX_IME];
 10    char prezime[MAX_PREZIME];
 11    unsigned ostvareni_bodovi;
 12    struct kandidati_st *sledeci;
 13} KANDIDAT;
 14
 15FILE *safe_fopen(char *, char *, int);
 16void ucitaj_kandidate(FILE *, KANDIDAT **);
 17void ispisi_preliminarnu_listu(FILE *, KANDIDAT *, unsigned);
 18
 19void inicijalizacija(KANDIDAT **);
 20KANDIDAT *napravi_cvor(char *, char *, unsigned);
 21void dodaj_sortirano(KANDIDAT **, KANDIDAT *);
 22void konvertuj_brojeve_telefona(KANDIDAT *);
 23void obrisi_listu(KANDIDAT **);
 24
 25int main(int argc, char **argv) {
 26    KANDIDAT *glava;
 27
 28    if(argc != 4) {
 29        printf("Primer poziva: %s kandidati.txt preliminarna-lista.txt 5\n", argv[0]);
 30        exit(EXIT_FAILURE);
 31    }
 32
 33    inicijalizacija(&glava);
 34
 35    FILE *ulazna = safe_fopen(argv[1], "r", 3);
 36    ucitaj_kandidate(ulazna, &glava);
 37    fclose(ulazna);
 38
 39    unsigned broj_primljenih = atoi(argv[3]);
 40    FILE *izlazna = safe_fopen(argv[2], "w", 4);
 41    ispisi_preliminarnu_listu(izlazna, glava, broj_primljenih);
 42    fclose(izlazna);
 43
 44    obrisi_listu(&glava);
 45
 46    return EXIT_SUCCESS;
 47}
 48
 49FILE *safe_fopen(char *name, char *mode, int error_code) {
 50    FILE *fp = fopen(name, mode);
 51
 52    if(fp == NULL) {
 53        printf("Nije moguce otvoriti fajl %s!\n", name);
 54        exit(error_code);
 55    }
 56
 57    return fp;
 58}
 59
 60void ucitaj_kandidate(FILE *ulazna, KANDIDAT **pglava) {
 61    char tmp_ime[MAX_IME];
 62    char tmp_prezime[MAX_PREZIME];
 63    unsigned tmp_ostvareni_bodovi;
 64
 65    while(fscanf(ulazna, "%s %s %u",
 66                 tmp_ime,
 67                 tmp_prezime,
 68                 &tmp_ostvareni_bodovi
 69          ) != EOF) {
 70        KANDIDAT *novi = napravi_cvor(tmp_ime, tmp_prezime, tmp_ostvareni_bodovi);
 71        dodaj_sortirano(pglava, novi);
 72    }
 73}
 74
 75void ispisi_preliminarnu_listu(FILE *izlazna, KANDIDAT *glava, unsigned broj_primljenih) {
 76    unsigned redni_broj = 1;
 77    KANDIDAT *tekuci = glava;
 78
 79    while(tekuci != NULL) {
 80        fprintf(izlazna, "%2u. %-7s %-7s %2u\n", 
 81            redni_broj, tekuci->ime, tekuci->prezime, tekuci->ostvareni_bodovi);
 82
 83        if(redni_broj == broj_primljenih) {
 84            fprintf(izlazna, "------------------------------\n");
 85        }
 86
 87        redni_broj++;
 88        tekuci = tekuci->sledeci;
 89    }
 90}
 91
 92void inicijalizacija(KANDIDAT **pglava) {
 93    *pglava = NULL;
 94}
 95
 96KANDIDAT *napravi_cvor(char *ime, char *prezime, unsigned ostvareni_bodovi) {
 97    KANDIDAT *novi = (KANDIDAT *) malloc(sizeof(KANDIDAT));
 98
 99    if(novi == NULL) {
100        printf("Greska prilikom zauzimanja memorije!\n");
101        exit(2);
102    }
103
104    strcpy(novi->ime, ime);
105    strcpy(novi->prezime, prezime);
106    novi->ostvareni_bodovi = ostvareni_bodovi;
107
108    novi->sledeci = NULL;
109
110    return novi;
111}
112
113void dodaj_sortirano(KANDIDAT **pglava, KANDIDAT *novi) {
114    if(*pglava == NULL ||
115       (*pglava)->ostvareni_bodovi < novi->ostvareni_bodovi) {
116        novi->sledeci = *pglava;
117        *pglava = novi;
118    } else {
119        KANDIDAT *tekuci = *pglava;
120
121        while(tekuci->sledeci != NULL &&
122              tekuci->sledeci->ostvareni_bodovi > novi->ostvareni_bodovi) {
123            tekuci = tekuci->sledeci;
124        }
125
126        novi->sledeci = tekuci->sledeci;
127        tekuci->sledeci = novi;
128    }
129}
130
131void obrisi_listu(KANDIDAT **pglava) {
132    KANDIDAT *tmp;
133
134    while(*pglava != NULL) {
135        tmp = *pglava;
136        *pglava = (*pglava)->sledeci;
137        tmp->sledeci = NULL;
138        free(tmp);
139    }
140}
141