[ cyber_killer @ 05.03.2007. 16:33 ] @
Imam sljedeci problem.Kako iz datoteke da prebroji sva slova abecede in na kraju izpise koliko puta se svako slovo u datoteci pojavi.Pri tome nije vazno jel
slovo veliko il malo.Kako bi na najkraci nacin napiso taj program.

Hvala unapred za pomoc.
[ X Files @ 05.03.2007. 17:46 ] @
cyber_killer,

Po pravilima ovog foruma brišu se sve teme u kojima autor traži da mu se uradi (domaći) zadatak
a da ništa sam nije prethodno pokušao. Pošto ti je ovo prvo pitanje na ES-u, neću ga brisati, ali
barem se potrudi da uradiš koliko znaš, kasnije će ti neko sigurno pomoći.

Pozdrav.
[ Wajda.W @ 06.03.2007. 10:47 ] @
imas funkciju fgetc(FILE *)
ova funkcija ti cita iz txt-a redom znak po znak dok ne naidje na kraj
npr:
Code:

int a;
char c;
FILE *fp;
while((c=getc(fp))!=EOF)
if ((c=='a')||(c=='A')) a++;

tako otprilike ide , EOF ti je kraj fajla ili ti End Of File
to mozes za sva slova ili znakove da proveravas
[ cyber_killer @ 06.03.2007. 12:10 ] @
Jel to gleda samo slovo a i A.Meni treba da izpise sva slova.Izpis bi trebo biti na ovakav nacin.

Slova a je:10;
Slova b je:12; itd.

Ja sam dosad uspio samo izpisati citavu datoteku.I probavo sam npr.da mi izpise znak npr. znak za dolar.

Evo moje kode za izpisivanje citavog fajla:

Code:
#include <stdio.h>

main(int argc, char *argv)
{
    FILE *pf;
    int c;
    int n =0;

    if(argc < 2)
        exit(2);
    pf=fopen("Izpis.txt" , "r");
    if( pf == NULL)
        perror ("Greska u otvaranju fajla");
        //exit(1);
    while( (c=fgetc(pf) ) != EOF)
        fputc(c, stdout);
    fclose(pf);
    exit(0);
}
    // pa sam onda probavo ovo za znak dolar al mi ne izpise nista

        do
        {
            c=fgetc(pf);
                if(c == '$') 
            n++;
        
                }  while(c != EOF);
            fclose(pf);
                    exit(0);
            printf("Znakova je %d$.\n", n);
            return(0);
        }

[ Wajda.W @ 06.03.2007. 13:16 ] @
pa probaj sa while(c=fgetc()!=EOF)
a ne sa do while petljom
I koliko sam ja to video tebi je pokazivac pozicioniran na kreju datoteke kada hoces da iz njnega citas.
Moras ga vratiti na pocetak datoteke ili sa rewind()
ili samo zatvoris i ponovo otvoris datoteku za citanje.
Code:
main(int argc, char *argv)
{
    FILE *pf;
    int c;
    int n =0;

    if(argc < 2)
        exit(2);
    pf=fopen("Izpis.txt" , "r");
    if( pf == NULL)
        perror ("Greska u otvaranju fajla");
        //exit(1);
    while( (c=fgetc(pf) ) != EOF)
        fputc(c, stdout);
    fclose(pf);// ovde si zatvorio datoteku
    exit(0);
}
    // 

        do
        {
            c=fgetc(pf);// da bi ovde citao moras prvo ponovo otvoriti datoteku
                if(c == '$') 
            n++;
        
                }  while(c != EOF);
            fclose(pf);
                    exit(0);
            printf("Znakova je %d$.\n", n);
            return(0);
        }

a sto se tice za $ ili za A(a) i bilo koje drugo slovo samo napisi vise if uslova
npr:
Code:

if((c=='a')||(c=='A')) a++;
if((c=='b')||(c=='B')) b++;
.
.
.

tako mozes za svako slovo samo ti treba isto toliko promenljivih.
mislim da ti neradi sto si zaboravio ponovo da otvoris datoteku
[ cyber_killer @ 06.03.2007. 13:52 ] @
Uff.Mislim da bi bilo to puno ifova.26 za englesku abecedu.I jos 26 printf .Znas li koji bolji nacin za to.Ako ja prije uspijem javit cu.

[ Wajda.W @ 06.03.2007. 14:04 ] @
ne znam stvarno nista mi ne pada na pamet a da je jednostavnije.
sto se tice printf f-je o mozes sve napisati u jednoj
printf("A: %d\n/
B: %d\n/",...);...

/ sa ovom crtom mozes da predjes u novi red bez da ponovo pises printf
a za ovo ostalo mozda moze nekako preko for petlje
Code:

for(i=65;i<92;i++)
if(i==c) ...

samo ne znam da li mozes porediti int sa char ovako i ne znam kako bi posle odredio brojac.
u svakom slucaju moras imati 26 zasebnih brojaca.
i ti ovde predstavlja ascii kod i ide od A do Z
znaci morao bi i mala slova pretvarati u velika(to nije tesko)
i onda ne dobijas jednostavniji nacin
[ SuPeR_MaSteR @ 06.03.2007. 20:59 ] @
Daj ljudi, kakvih 26 brojaca, evo jednog veoma jednostavnog resenja:
Code:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int slovo(char* a);
int main()
{
    const int pomeraj = 97;
    const int brSlova = 26; /* eng. alfabet */
    int frekv[brSlova], i;
    char c;
    FILE* file = fopen("nekiTekstualniFajl.txt"r");
    for (i = 0; i < brSlova; frekv[i++] = 0);
    while (!feof(file))
    {
        c = fgetc(file);
        if (slovo(&c))
           frekv[c-pomeraj]++;
    }
    for (i = 0, c = 'a'; i < brSlova; i++, c++)
        printf("Frekvencija slova %c = %d\n", c, frekv[i]);
    fclose(file);
    return 0;
}
int slovo(char* a)
{
    if (isalpha(*a))
    {
        if (isupper(*a))
           *a = tolower(*a);
        return 1;
    }
    return 0;
}
[ cyber_killer @ 06.03.2007. 21:37 ] @
Super je ta koda i hvala sto si se potrudio pa uradio je.Ali gledaj ja sa takvom kodom da izadjem pred profesora je malo varljivo.
Odma bi znao da je sam nisam napisao.Znaci trebam njesto jednostavnije.Mozda se tebi cini to vrlo jednostavno ali za jednog pocetnika je to malo previse.Ako mozes barem malo prekomentirati kodu, bilo bi mi lakse.Kad si se vec toliko "namucio" u pisanju ako ti jos to nije tesko. :D
[ SuPeR_MaSteR @ 06.03.2007. 22:05 ] @
Code:
for (i = 0; i < brSlova; frekv[i++] = 0);

Niz frekv sluzi za pamcenje broja pojavljivanja pojedinacno svakog znaka abecede. U ovom delu koda sve elemente postavljam na nulu jer, naravno, odatle krece brojanje.
Code:
while (!feof(file))

Funkcija feof() je upotrebljena kao indikator kraja fajla, vraca nenultu vrednost ako procita kod EOF (End Of File), odnosno nulu u suprotnom. Kao argument uzima pokazivac na FILE.
Prevedeno na srpski ova linija zvuci kao: "Dok nije kraj fajla"
Code:
if (slovo(&c))

Ako je procitani znak slovo onda sledi:
Code:
frekv[c-pomeraj]++;

Simbol 'a' ima ASCII kod 97, tako da njegovim oduzimanjem sa vrednoscu varijable pomeraj (tj. brojem 97) dobijamo 0 koja nam sluzi za indeksiranje niza, sto znaci da ce slovo 'b' imati index 98-97 = 1, slovo 'c' 99-97 = 2 i tako redom..
Ovaj deo koda nam sluzi za brojanje pojavljivanja znakova.
Code:
int slovo(char* a)

Funkcija slovo() kao argument uzima pokazivac na tip char, to sam koristio da bih u slucaju potrebe mogao izmeniti stvarni podatak.
Code:
if (isalpha(*a))

Ako je sadrzaj pokazivaca a (odnosno ucitani znak c) slovo:
Code:
if (isupper(*a))

Da li je sadrzaj pokazivaca a (odnosno ucitani znak c) veliko slovo?
Code:
*a = tolower(*a);

U slucaju da jeste, pomocu funkcije tolower() pretvara se u malo.
Code:
return 1;

Ako je prvi uslov (isalpha(*a)) ispunjen, povratna vrednost je logicka istina (1), u suprotnom funkcija vraca logicku neistinu (0) i vrednost odgovarajuceg elementa niza frekv se NE inkrementira.

Nadam se da ce biti jasnije, ako nesto nije jasno slobodno pitaj
[ Wajda.W @ 07.03.2007. 13:18 ] @
Vidis da mora imati 26 brojaca sam si ih smestio u jednodimenzionalni niz
[ cyber_killer @ 07.03.2007. 19:17 ] @
Code:

int slovo(char* a)
{
    if (isalpha(*a))
    {
        if (isupper(*a))
           *a = tolower(*a);
        return 1;
    }
    return 0;
}


Do ovog djela mi je sve jasno.Samo ovog bas ne razumijem sta ova funcija radi.Ja sam to razumijo da samo provjerava jel slovo, i da pretvori ako je malo u veliko slovo.A i ovaj pokazivac mi nije jasan,jer mi ni nismo jos uzimali pokazivace,ja sam to sam malo cito,tako da ne razumijem najbolje.

Aha jos sam zaboravio za ovo for (i = 0, c = 'a'; i < brSlova; i++, c++) a to je samo za izpis sluzi.I jos ovaj if(slovo(&c)) Zasto ovaj &?

[Ovu poruku je menjao cyber_killer dana 07.03.2007. u 20:59 GMT+1]
[ SuPeR_MaSteR @ 07.03.2007. 22:48 ] @
Citat:
Wajda.W: Vidis da mora imati 26 brojaca sam si ih smestio u jednodimenzionalni niz

Nesporazum, kad si rekao 26 brojaca pomislio sam na 26 varijabli posebno.

@cyber_killer, ne mogu ti sad objasnjavati sta su pokazivaci... ja nisam znao sta ste ucili a sta niste, cudno je da ste radili datoteke a niste pokazivace (bar zbog file pointer-a koji se koristi).
Moze i bez te funkcije:
Code:

#include <stdio.h>
#include <ctype.h>
.................
.................
while (!feof(file))
{
    c = fgetc(file);
        if (isalpha(c))
        {
           if (isupper(c))
               c = tolower(c);
           frekv[c-pomeraj]++;
        }
}
.................
.................
fclose(file);
return 0;
}


E sad, petlju sam koristio za ispis (posto je u pitanju niz):
Code:
for (i = 0, c = 'a'; i < brSlova; i++, c++)
   // ispisi a, b, c ... itd.

i varijabla mi oznacava pomocnu promenljivu pri ciklusu (i naravno za dohvatanje elemenata niza), a varijabla c mi sluzi za ispis znakova abecede, inkrementiranjem pri svakom prolazu njena celobrojna vrednost se povecava za 1 i tako dobijam sledece slovo abecede (pogledaj ASCII tabelu)
[ Wajda.W @ 08.03.2007. 09:24 ] @
imas i ovu foru za pretvaranje slova iz malih u velika,mada je ona bolja
Code:

if((c>='a')&&(c<='z')) c=c-'a'+'A';

ili samo napises razliku u ascii kodovima izmedju velikog i malog (malo a je 97, a veliko 65)
mozes i c=c-32;
a za iz velikih u ,ala obrnuto.
[ cyber_killer @ 08.03.2007. 19:08 ] @
Ok.Hvala sad sve razumijem.Vidimo se do sljedeceg problema,nadam se da jih nece biti puno.