[1] Moderne aplikacije :: Školski dani

[1] Moderne aplikacije :: Školski dani

offline
  • Srđan Tot
  • Am I evil? I am man, yes I am.
  • Pridružio: 12 Jul 2005
  • Poruke: 2483
  • Gde živiš: Ljubljana

Internet serveri



Potrebno znanje za praćenje teksta:
Osnovno korišćenje Visual C++-a

Ako ste imali sreću, u školi ste imali dobrog nastavnika informatike, i naučio vas je da rešavate matematičke problema uz pomoć programiranja. Ako ste imali još više sreće, naučili ste i da pravite po koju grafičku aplikacija. Ako ste bili veoma srećni, naučili ste i da razmišljate kao programeri.

Bilo kako bilo, većina vas je stigla do pravljenja konzolnih aplikacija i razumevanja osnovnih principa u programiranju. Verovali ili ne, to znanje je dovoljno za pravljenje jednostavnih, modernih aplikacija. Cilj ovog teksta je da vas provede kroz aplikaciju za unos i pretragu imenika, sve od jednostavne, konzolne aplikacije, pa do moderne, grafičke koja zna da radi s podacima koji se nalaze na internetu. Za razumevanje i praćenje teksta, morate poznavati osnovne termine u programiranju, a preporučljivo je i da znate C++ jezik (svi jezici koje ćemo kasnije koristiti su vrlo slični C++-u).

Kao što već rekoh, počećemo s konzolnom aplikacijom. Recimo da vam je profesor dao zadatak da napravite imenik, i vi u glavi već vidite kako ćete napraviti unos podataka, brisanje, pretragu i, kao bonus, snimanje i učitavanje na disk. Takva aplikacija bi sigurno zaslužila odličnu ocenu.

Palimo računar, instaliramo Visual Studio 2012 Express ako ga već nemamo, pravimo nov konzolni projekat i praznu datoteku za naš kod. Pošto želimo da napravimo dobar program, sada zastajemo da razmislimo kako želimo da organizujemo program.

Definitivno želimo da napravimo strukturu i pomoćne funkcije za rad sa podacima, koje moraju da rade bez obzira na način prikazivanja podataka. Želimo da iz programa izvučemo delove koda koji se često ponavljaju i od njih napravimo funkcije. Želimo da program rastavimo na akcije, tako što ćemo svaku akciju definisati u odvojenoj funkciji, koja može da radi neodvisno od drugih. Za kraj, želimo sve te funkcije da grupišemo u jedan fin, glavni meni.

Počnimo s tipom koji će služiti za čuvanje podataka:
struct Person {    char name[50], address[50], phone[50], email[50]; };
Ovaj tip podatka će nam omogućiti čuvanje imena, adrese, telefona i email-a upisanih osoba. Svako polje može sadržati maksimalno 49 znakova (jedan znak je rezervisan za tzv. NULL znak, kojim se označava kraj stringa).

Uz pomoć ovog tipa, moramo napraviti internu bazu u kojoj ćemo zapisati podatke. Za tu svrhu ćemo iskoristiti običan niz i jedan broj koji će nam kazati koliko podataka ima u tom nizu:
struct Person persons[100]; int personCount = 0;
To je naša interna baza. Omogućava unos maksimalno 100 osoba.

Odlično… sada možemo preći na funkcije za rad sa ovim podacima. Da krenemo od najjednostavnije… funkcija za prikaz podataka o jednoj osobi:
void printPerson(int i) {    printf("Ime: %s\n", persons[i].name);    printf("Adresa: %s\n", persons[i].address);    printf("Telefon: %s\n", persons[i].phone);    printf("Email: %s\n\n", persons[i].email); }
Jednostavan ispis svakog polja na ekran.

Sledeća funkcija će biti postavljanje polja za određen zapis u bazi. Želimo da ova funkcija omogućava čitanje cele linije, ali i očuvanje stare vrednosti u slučaju da korisnik unese praznu liniju. Zbog toga ćemo napraviti i jednu pomoćnu funkciju za unos podataka:
void readLine(char *line) {    fflush(stdin);    gets(line); } void updatePerson(int i) {    char str[50];    printf("Ime [%s]: ", persons[i].name);    readLine(str);    if (strlen(str) > 0)       strcpy(persons[i].name, str);    printf("Adresa [%s]: ", persons[i].address);    readLine(str);    if (strlen(str) > 0)       strcpy(persons[i].address, str);    printf("Telefon [%s]: ", persons[i].phone);    readLine(str);    if (strlen(str) > 0)       strcpy(persons[i].phone, str);    printf("Email [%s]: ", persons[i].email);    readLine(str);    if (strlen(str) > 0)       strcpy(persons[i].email, str); }
Pomoćna funkcija readLine, za razliku od funkcije scanf, vraća i prazna mesta i praznu liniju u slučaju da korisnik samo pritisne Enter. U funkciji za upis podataka, prikazujemo trenutnu vrednost polja i menjamo je samo u slučaju da je korisnik uneo novu vrednost.

Od funkcija za uređivanje podataka nam nedostaje samo još funkcija za brisanje:
void removePerson(int i) {    int j;    for (j = i; j < personCount - 1; ++j)       persons[j] = persons[j + 1];    --personCount;    strcpy(persons[personCount].name, "");    strcpy(persons[personCount].address, "");    strcpy(persons[personCount].phone, "");    strcpy(persons[personCount].email, ""); }
Sve podatke koji se nalaze ispred izbrisanog zapisa, pomeramo za jedno mesto nazad, i iz zadnjeg zapisa brišemo sve podatke. Na taj način ne ostavljamo rupe u našoj bazi i time izbegavamo fragmentaciju na račun brzine izvršavanja, koja nam, u ovom slučaju, nije mnogo bitna, jer nemamo previše podataka.

Sad možemo napraviti glavni meni koji će korisniku ponuditi listu akcija:
void main() {    int done = 0, action;    printf("-=[ Imenik ]=-\n");    while (!done)    {       printf("\n.: Akcije :.\n");       printf("  [1] Pretraga imenika\n");       printf(" ---------------------------------------\n");       printf("  [2] Unos nove osobe\n");       printf("  [3] Promena podataka upisane osobe\n");       printf("  [4] Brisanje osobe\n");       printf(" ---------------------------------------\n");       printf("  [5] Snimanje na disk\n");       printf("  [6] Ucitavanje sa diska\n");       printf(" ---------------------------------------\n");       printf("  [0] Izlaz\n\n");       printf("Izaberite akciju [0-6]: ");       scanf("%d", &action);       while (action < 0 || action > 6)       {          printf("Nepravilna akcija!\n");          printf("Izaberite akciju [0-6]: ");          scanf("%d", &action);       }       switch (action)       {       case 1:          search();          break;       case 2:          addPerson();          break;       case 3:          editPerson();          break;       case 4:          deletePerson();          break;       case 5:          savePersons();          break;       case 6:          loadPersons();          break;       default:          done = 1;          break;       }    } }
Ovo je naša glavna petlja. Taj deo koda će se vrteti sve dok korisnik ne odluči da zatvori program.

Svaku akciju smo odvojili u posebnu proceduru. Počnimo od najjednostavnije… dodavanje novog zapisa:
void addPerson() {    printf("\n.: Unos nove osobe :.\n");    updatePerson(personCount++); }
To je to. Zahvaljujući pomoćnim funkcijama, dovoljno je da pokrenemo uređivanje prvog slobodnog zapisa, i zatim povećamo broj zapisa za 1.

Uređivanje zapisa je slično unosu novog. Razlika je u tome što moramo izabrati koji zapis želimo da menjamo:
void editPerson() {    int i;    printf("\n.: Promena podataka upisane osobe :.\n");    printf("Redni broj osobe: ");    scanf("%d", &i);    if (i < 0 || i >= personCount)       printf("Ne postoji osoba s tim rednim brojem!\n");    else       updatePerson(i); }

Prateći isti šablon, pravimo i funkciju za brisanje zapisa:
void deletePerson() {    int i;    printf("\n.: Brisanje osobe :.\n");    printf("Redni broj osobe: ");    scanf("%d", &i);    if (i < 0 || i >= personCount)       printf("Ne postoji osoba s tim rednim brojem!\n");    else       removePerson(i); }

Sad na malo, ali samo malo težu funkciju. Traženje se svodi na proveravanje da li se uneti tekst nalazi u nekom od polja, i prikaza zapisa koji sadrži to polje:
void search() {    char searchStr[50];    int i, count = 0;    printf("\n.: Pretraga imenika :.\n");    printf("Pretraga: ");    readLine(searchStr);    for (i = 0; i < personCount; ++i)    {       if (strstr(persons[i].name, searchStr) || strstr(persons[i].address, searchStr) || strstr(persons[i].phone, searchStr) || strstr(persons[i].email, searchStr))       {          printPerson(i);          ++count;       }    }    printf("Broj rezultata: %d\n", count); }

Sada na red dolaze bonus… funkcije za čuvanje i čitanje podataka. Čuvanje podataka se svodi na ispis svih podataka u datoteku:
void savePersons() {    char fileName[FILENAME_MAX];    FILE *f;    int i;    printf("\n.: Snimanje na disk :.\n");    printf("Unesite ime datoteke: ");    readLine(fileName);    f = fopen(fileName, "w");    if (f)    {       fprintf(f, "%d\n", personCount);       for (i = 0; i < personCount; ++i)       {          fputs(persons[i].name, f);          fprintf(f, "\n");          fputs(persons[i].address, f);          fprintf(f, "\n");          fputs(persons[i].phone, f);          fprintf(f, "\n");          fputs(persons[i].email, f);          fprintf(f, "\n");       }       fclose(f);    }    else       printf("Doslo je do greske prilikom otvaranja datoteke \"%s\".\n", fileName); }

Funkcija za učitavanje podataka zahteva mogućnost čitanja cele linije, ali i mogućnost čitanja praznih redova iz datoteke. Zbog toga ćemo napisati i jednu pomoćnu funkciju koja radi baš to:
void freadLine(FILE *f, char *line) {    char str[50];    char *nl;    fgets(str, 50, f);    nl = strchr(str, '\n');    if (nl)       *nl = '\0';    strcpy(line, str); } void loadPersons() {    char fileName[FILENAME_MAX];    FILE *f;    int i;    printf("\n.: Ucitavanje sa diska :.\n");    printf("Unesite ime datoteke: ");    readLine(fileName);    f = fopen(fileName, "r");    if (f)    {       while (personCount)          removePerson(personCount - 1);       fscanf(f, "%d\n", &personCount);       for (i = 0; i < personCount; ++i)       {          freadLine(f, persons[i].name);          freadLine(f, persons[i].address);          freadLine(f, persons[i].phone);          freadLine(f, persons[i].email);       }       fclose(f);    }    else       printf("Doslo je do greske prilikom otvaranja datoteke \"%s\".\n", fileName); }

To je naš program. Fino razdvojen na celine, lak za održavanje i uklanjanje eventualnih grešaka, i program koji bi dobio odličnu ocenu. Iako bi ovaj program u školi prošao sasvim dobro, u pravom svetu je prilično nepraktičan. Omogućava rad sa malim brojem podataka, pokušaj unosa većeg broja bi izazvalo greške zbog kojih bi se program srušio, prikaz podataka je nepregledan, itd… Da bismo napredovali od ovakvog do modernijeg programa, moraćemo naučiti da koristimo nove alate i jezike. Srećom, znanje koje smo do sada stekli će nam dati veliku prednost u savladavanju tih novih stvari koje nas očekuju.

[url=https://www.mycity.rs/must-login.png kod projekta[/url]



Internet serveri



Registruj se da bi učestvovao u diskusiji. Registrovanim korisnicima se NE prikazuju reklame unutar poruka.
Ko je trenutno na forumu
 

Ukupno su 596 korisnika na forumu :: 28 registrovanih, 7 sakrivenih i 561 gosta   ::   [ Administrator ] [ Supermoderator ] [ Moderator ] :: Detaljnije

Najviše korisnika na forumu ikad bilo je 1567 - dana 15 Jul 2016 19:18

Korisnici koji su trenutno na forumu:
Korisnici trenutno na forumu: 357magnum, 8u47, A.R.Chafee.Jr., AMCXXL, aramis s, bane.gr, dekao, ekser222, imperator10, indja, KUZMAR, liman, Mali Veseljak, milandlc84.wow, nikoladi, nuke92, panticstefan53, Raptor1, rkekoke, S-lash, sakota79, shaja1, Skywhaler, stug, vasa.93, Vlad000, vlvl, Wisdomseeker