[ overdose @ 20.11.2004. 10:46 ] @
Zadatak:

Napisati program na programskom jeziku C koji radi sa dve tekstualne datoteke. Prvo se sa standardnog ulaza učitava ime ulazne datoteke, a zatim ime izlazne datoteke. Prepostaviti da imena datoteka ne mogu biti duža od 40 znakova. U ulaznoj datoteci se nalaze podaci o studentima, u sledećem formatu (ggbbbb Ime Prezime, gde gg predstavlja poslednje dve cifre godine upisa, a bbbb redni broj indeksa, godine upisa su od 1950. do 2049. godine):

010234 Ivana Ivanovic
990987 Marko Markovic
...

Potrebno je u izlaznu datoteku upisati modifikovane podatke, po sledećem formatu (bbbb/gggg Ime Prezime, gde gggg predstavlja sve četiri cifre godine upisa):

0234/2001 Ivana Ivanovic
0987/1999 Marko Markovic
...

Broj linija u ulaznoj datoteci nije unapred poznat. Transformaciju formata ggbbbb u bbbb/gggg vršiti u posebnoj funkciji SrediGodinu, kojoj se kao parametri prosleđuju dva stringa fiksne dužine, definisana u glavnom programu. Funkcija treba da vrati 0 ako godina upisa nije veća od 1999, odnosno 1 ako nije manja od 2000. U glavnom programu treba brojati pojavljivanja i jednog i drugog rezultata, i ispisati ih na standardnom izlazu na kraju izvršavanja programa.

Ulaz:

Code:

010234 Ivana Ivanovic
990987 Marko Markovic


Moje rešenje:

Code:

#include <stdio.h>

int SrediGodinu (char red_stari[], char red_novi[]) {
  int ind, god;
  char godina[1024], broj[5], ime[20], prezime[20], crta[]="/", olos[]="19", dobar[]="20", space[]=" ", novi[]="\n";
  sscanf (red_stari, "%d%s%s", &ind, ime, prezime);
  god=ind/10000;
  godina[0]=red_stari[0]; godina[1]=red_stari[1];  
  broj[0]=red_stari[2]; broj[1]=red_stari[3]; broj[2]=red_stari[4]; broj[3]=red_stari[5];
  if (god >= 50 && god <= 99) {
    sprintf (red_novi, "%s%s%s%s%s%s%s%s%s", broj, crta, olos, godina, space, ime, space, prezime, novi);
    return 0;
  }
  else if (god >= 00 && god <= 49) {
    sprintf (red_novi, "%s%s%s%s%s%s%s%s%s", broj, crta, dobar, godina, space, ime, space, prezime, novi);
    return 1;
  }
  else return 2;
}

void main () {
  int indikator, student_olos=0, student_dobar=0;
  char ulaz[40], izlaz[40], red_stari[1024], red_novi[1024];
  FILE *ul, *izl;
  printf ("Unesite ime ulazne datoteke: "); scanf ("%s", ulaz);
  printf ("Unesite ime izlazne datoteke: "); scanf ("%s", izlaz);
  ul=fopen (ulaz, "r");
  izl=fopen (izlaz, "w");
  while ((fgets (red_stari, 101, ul)) != NULL) {
    if ((indikator=SrediGodinu(red_stari, red_novi))==0) student_olos++;
    else if (indikator==1) student_dobar++;
    else if (indikator==2) printf ("Greska: izasli smo iz opsega godina !\a\n");
    fputs (red_novi, izl);
  }
  printf ("\nStarijih studenata ima %d, a novijih %d.\n\n", student_olos, student_dobar);
}


E ovako super radi, ali kada za dužinu stringa red_stari ili red_novi stavim npr. 100 (jer i neće biti duži od toga) dolazi do lošeg formatiranja na izlazu (neki čudni karakteri). Ili ako za dužinu stringa godina stavim 4 ili 5 (jer sigurno nije duži od toga) opet slični problemi !

U čemu je problem ?

OvEr
[ Vertyg01 @ 22.11.2004. 01:16 ] @
Jao pa zar si morao ovo toliko iskomplikovati !!!
trebao si da koristis StrTok funkciju !!! i lakse bi mozda islo da si isao sa pointer to char ...
[ filjo @ 22.11.2004. 04:43 ] @
To sto si smanjio broj linija koda za 1/2 nece da pomogne. Muka je da se gleda. Daj formatizuj to kako treba.

Za par godina ni ti sam neces moci da procitas ono sto si napisao...
[ filjo @ 22.11.2004. 04:59 ] @
Code:
#include <stdio.h>

int SrediGodinu (char red_stari[], char red_novi[])  {
int ind, god;
char godina[1024], broj[5], ime[20], prezime[20];
char crta[]="/", olos[]="19",dobar[], space[]=" ", novi[]="\n";
    sscanf (red_stari, "%d%s%s", &ind, ime, prezime);
    god=ind/10000;
    godina[0]=red_stari[0];
    godina[1]=red_stari[1];  
    broj[0]=red_stari[2]; 
    broj[1]=red_stari[3];
    broj[2]=red_stari[4];
    broj[3]=red_stari[5];
    if (god >= 50 && god <= 99)  {
       sprintf (red_novi, "%s%s%s%s%s%s%s%s%s", broj, crta, olos, godina, space, ime, space, prezime, novi);
       return 0;
    }  
    else if (god >= 00 && god <= 49)  {
        sprintf (red_novi, "%s%s%s%s%s%s%s%s%s", broj, crta, dobar, godina, space, ime, space, prezime, novi);
        return 1;
    }
    else return 2;
}

void main () {
  int indikator, student_olos=0, student_dobar=0;
  char ulaz[40], izlaz[40], red_stari[1024], red_novi[1024];
  FILE *ul, *izl;
  printf ("Unesite ime ulazne datoteke: ");
  scanf ("%s", ulaz);
  printf ("Unesite ime izlazne datoteke: ");
  scanf ("%s", izlaz);
  ul=fopen (ulaz, "r");
  izl=fopen (izlaz, "w");
  while ((fgets (red_stari, 101, ul)) != NULL) {
    if ((indikator=SrediGodinu(red_stari, red_novi))==0) 
       student_olos++;
    else if (indikator==1) 
       student_dobar++;
    else if (indikator==2) 
       printf ("Greska: izasli smo iz opsega godina !\a\n");
    fputs (red_novi, izl);
  }
  printf ("\nStarijih studenata ima %d, a novijih %d.\n\n", student_olos, student_dobar);
}
[ overdose @ 22.11.2004. 10:40 ] @
man strtok

BUGS

Never use these functions. If you do, note that:

These functions modify their first argument.
These functions cannot be used on constant strings.
The identity of the delimiting character is lost.
The strtok() function uses a static buffer while parsing, so it's not thread safe. Use strtok_r() if this matters to you.


Ne kapiram zašto je komplikovano ?
[ Vertyg01 @ 22.11.2004. 11:06 ] @
Ma nije komplikovano!!!
Pokusao sam da ispravim gresku.

sscanf (red_stari, "%d%s%s", &ind, ime, prezime);
god=ind/10000;
broj1=(ind % 1000);
printf("%d\n\n",broj1);

if (god >= 50 && god <= 99) {
red_novi[0]=intToStr(broj1);
red_novi[1]= crta;
mi=1900+god;
red_novi[2]=intToStr(mi);
red_novi[3]= space;
red_novi[4]= ime;
red_novi[5]= space;
red_novi[6]= prezime;
red_novi[7]= novi;
return 0;
}
else if (god >= 00 && god <= 49) {
red_novi[0]=intToStr(broj1);
red_novi[1]= crta;
mi=2000+god;
red_novi[2]=intToStr(mi);
red_novi[3]= space;
red_novi[4]= ime;
red_novi[5]= space;
red_novi[6]= prezime;
red_novi[7]= novi;
return 1;
}
else return 2;
}

.... ali isti rezultat. Jedan od problema je sto:
kada promjenjivu red_stari prenesemo u SrediGodinu i pokusamo je ispisati dolazi sa viskom elemenata:
printf("%s",red_stari); --->> 010234 Ivana Ivanovic234
znaci do greske dolazi na ulazu funkcije ...