*p2; - széchenyi istván egyetemherno/ngb_in001_2/prog2.pdf · 17 •olvasson be a szabvány...

156
Programozás II. Horváth Ernő *p2;

Upload: others

Post on 30-Aug-2019

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

Programozás II.

Horváth Ernő

*p2;

Page 2: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

2

ANSI C adattípusok

Cím szerinti paraméter átadás

Mutatók

Mutatók és tömbök

Mutatótömbök

Dinamikus memóriakezelés

Malloc, Calloc, Free, Realloc

Random

Typedef , Struktúrák

State machine – állapotgép

Linked list (láncolt lista)

Fájlkezelés

Helyi beállítások

Időkezelés

Feladat char * 01

Feladat char * 02

Feladat valós zámok tömbbe mutatókkal

Feladat memóriafoglalás

Feladat - Dinamikus tömb 02

Feladat - Dinamikus tömb 03

Feladat - törlés láncolt listából

Feladat - láncolt lista megfordítás

Feladat – fájlolvasás

Feladat - függvénymutató

Összes feladatmegoldás

Összes feladatleírás

Page 3: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

3

Elérhetőségek

Hatwágner Ferenc Miklós

http://www.sze.hu/~hatwagnf/

[email protected]

Horváth Ernő

http://www.sze.hu/~herno/

Tanszéki honlap

http://it.sze.hu

Page 4: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;A félév

1-3. hét Karaktermutatók. Karakterlánc (string) kezelő függvények.

Mutatótömbök. Többdimenziós tömbök. Dinamikus memóriakezelés.

Tömbök, mint függvényparaméterek. Parancssori paraméterek.

Függvénymutatók. Typedef. Algoritmusok: Pontosan ellenőrzött

bemenet.

4-5. hét Struktúrák és függvények. Uniók. Bitmezők. Névterületek.

Struktúratömbök pontokhoz, dátumkezeléshez. Dinamikus

adatszerkezetek: listák, fák

6-7. hét Magas szintű (stream) bemenet, kimenet. Változó paraméter lista.

Fájlok másolása, egyesítése, középre igazítás.

8-9. hét Helyi beállítások, széles karakterek, karakterláncok, időkezelés.

10- 14. hét Alacsony szintű (leírós) fájlkezelés. Könyvtárak kezelése, folymatok

(process) cső (pipe) kezelése. Jelkezelés (signal), foglalatok (socket).4

Page 5: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

5

Követelmények

• Vizsga– Vizsgaidőszakban

Alapfeladat 2es, minden plusz feladat után egy jeggyel jobb az

érdemjegy, de az alapfeladatnak működnie kell szintaktikai hiba

nélkül

• ZH nincs

• Beadandó feladat aláírásért » elearning.sze.hu

• Katalógus nincs

Page 6: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Kabinet használat

• Felhasználó név: EIK

• Jelszó nincs

• L:\ - írási jog, vizsgán ide kell a végső kódnak felkerülnie

• D:\ - írási jog

• C:\temp - ide érdemes dolgozni

• K:\GB_IN001_2 – vizsgán, órán ezek a feladatok

használhatóak

6

Page 7: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;K meghajtó

7

\\fs-kab.eik.sze.hu\szakkabinet\kozos\GB_IN001_2_Programozas_2

Page 8: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Tömör C kód mutatókkal

#include <stdio.h>

main(t,_,a)char *a;{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,

main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?

main(2,_+1,"%s %d %d\n"):9:16:t<0?t<-72?main(_,t,

"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+,/+#n+,/#\

;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l \

q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# \

){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' \

iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \

;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# \

}'+}##(!!/")

:t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1)

:0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a,

"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);}

8

On the first day of Christmas my true love ga ve to mea partridge in a pea r tree.

On the second day of Christmas my true love ga ve to metwo turtle dovesand a partridge in a pea r tree.

On the third day of Christmas my true love ga ve to methree french hens, two turtle dovesand a partridge in a pea r tree.

On the fourth day of Christmas my true love ga ve to mefour ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the fifth day of Christmas my true love ga ve to mefive gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the sixth day of Christmas my true love ga ve to mesix geese a-laying, five gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the seventh day of Christmas my true love ga ve to meseven swans a -swimming,six geese a-laying, five gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the eighth day of Christmas my true love ga ve to meeight maids a-milking, seven swans a -swimming,six geese a-laying, five gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the ninth day of Christmas my true love ga ve to menine ladies dancing, eight maids a-milking, seven swans a -swimming,six geese a-laying, five gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the tenth day of Christmas my true love ga ve to meten lords a-lea ping,nine ladies dancing, eight maids a-milking, seven swans a -swimming,six geese a-laying, five gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the e leventh day of Christmas my true love ga ve to meeleven pipers piping, ten lords a-lea ping,nine ladies dancing, eight maids a-milking, seven swans a -swimming,six geese a-laying, five gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

On the twelfth day of Christmas my true love ga ve to metwelve drummers drumming, eleven pipers piping, ten lords a-lea ping,nine ladies dancing, eight maids a-milking, seven swans a -swimming,six geese a-laying, five gold rings;four ca lling birds, three french hens, two turtle dovesand a partridge in a pea r tree.

Press any key to continue . . .

Page 9: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Pointerek, más néven mutatók

• A mutató olyan változó, amelyik memóriacímet tartalmaz. Létrehozása az indirekció operátorral (*) történik.

• int-re mutató típusos pointer:int * p;• típus nélküli pointer: void * p;• A változó nevéből a címképző (&) operátorral kaphatjuk meg

a változó címét: int x,*p;p=&x;

9Forrás: A programozás alapjai - Pohl László, Budapest, 2010

Page 10: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Mutatók

int n,*p;

p=&n;

n=6;

printf("%d\n", n); // n helyett írhattunk volna *p-t is

*p=5;

printf("%d\n", n); // n helyett írhattunk volna *p-t is

10

Futás:65

p címe pl. 0x0028F8D8értéke: 06

Page 11: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Cím szerinti paraméter átadás

void ertekSzerint(char x){

x = 22;

}

void cimSzerint(char *x){

*x = 33;

}

void main(){

char e = 1, c = 1;

ertekSzerint(e);

cimSzerint(&c);

printf("Ertek szerint: %d\nCim szerint: %d", e, c);

}

11

Futás:Ertek szerint: 1Cim szerint: 33

Page 12: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Csere mutatókkal

void csere(int *px, int *py){

int tmp;

tmp = *px;

*px = *py;

*py = tmp;

}

//a módosítandó értékek címének átadása

12

Main:

int a=22, b=1020;

csere(&a, &b);

printf("%d", b);

Futás:22

Page 13: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;NULL pointer

A NULL pointer egy olyan speciális mutatót jelent, amely nem mutat semmilyen változóra. Bármilyen

típusú pointer lehet NULL értékű.

if (ptr != NULL)

printf("Valahova mutat.\n");

if (ptr == NULL)

printf("Sehova sem mutat.\n");

if (ptr)

printf("Valahova mutat.\n");

if (!ptr)

printf("Sehova sem mutat.\n");

13

Page 14: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Mutatók és tömbök

• A mutatók jól használhatók tömbök bejárására, feldolgozására

• De a mutatók nem tömbök >> memória foglalás• A tömbnevének [ ] nélküli leírása egyenértékű a 0 indexű

elem címével. Például: tombom ugyanazt jelenti, mint &tombom[0].char x[100];char *m;m=&x[0];m=x;*(m+1); // egyenértékű x[1]

14

Page 15: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Mutatók és tömbök példa

int tombom[10];

*(tombom + 3) = 5;//vagy ugyanez másképp:tombom[3] = 5;

15

int *p = tombom;

*(p + 2) = 8;

//ugyanez:

p[2] = 8;

Gyakorlatilag [] indexelő operátort használva címszámítást és

indirekciót (dereferálást) is végzünk. A fordító a kezdőcímhez hozzáadja

az adott típusnak megfelelően foglalt memóriarészeket, így éri el az

adott elemet.

Page 16: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

Feladat legnagyobb - mutatókkal

int legnagyobb(int *tomb, int meret){int n;int max;max=tomb[0];for( n=1; n<meret; n=n+1 )

if( max<tomb[n] )max=tomb[n];

return(max);}

main(){int t[5];t[0]=49;t[1]=40;t[2]=22;

printf("Legnagyobb=%d\n", legnagyobb(t, 3) );getchar();

}

16

Page 17: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladatok char * 01

Készítse el az alább felsorolt, ismert C függvények mutatós változatát! A char * visszatérésű függvények az eredmény címével térnek vissza!• Sor beolvasása a szabvány bemnetről:int getline(char s[], int lim)int getline(char s*, int lim)

• c karakter törlése a karakterláncból:void squeeze(char s[], int c)char *squeeze(char s*, int c)

• Karakterlánc egésszé konvertálása:int atoi(char s[])int atoi(char s*))

17

Page 18: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

• Olvasson be a szabvány bemenetről egy karakterláncot! Egy

alkalmas függvény segítségével alakítsa át úgy a beolvasott

szöveget, hogy» eltávolítja belőle a fehér karaktereket,

» és az első szó kivételével minden szó kezdőbetűjét nagyra,

» az összes többi betűjét kisbetűre változtatja.

• Elegendő csak az angol abc jeleivel foglalkozni. Jelenítse is

meg az eredményt! A programban a tömbök elemeinek

elérésére mutatókat kell használni, indexelés nem fogadható

el!

Feladat – fehér karakter

18extra1.c

Valami aaa BBB CcCCvalamiAaaBbbCccc

Page 19: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Getline (mutatók nélkül)

• Szabvány bemenetről egy sor beolvasása.• A sor karaktereit rendre elhelyezi az s karaktertömbben. A

befejező soremelés karaktert nem viszi át a tömbbe, hanem helyette lánczáró '\0'–t ír a karakterlánc végére.

• Legfeljebb lim karaktert tárol a tömbben, visszatérési értéke

az s tömbben elhelyezett karakterlánc hossza.

19

Page 20: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;int getline(char s[],int lim){

int c, i;

for(i=0; i<lim && (c=getchar())!=EOF && !='\n'; ++i)

s[i]=c;

s[i]='\0';

while(c!=EOF && c!='\n')

getchar();

return(i);

}

20

Page 21: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Getline

• s[] indexelése helyett a t mutatóval haladunk az skaraktertömbön.

• A t mindig a következő szabad helyre mutat a tömbben,

melynek túlírását az n elfogyása akadályozza meg. n-->0• A karakterláncot záró '\0' címéből a tömb kezdőcímét

kivonva, éppen a karakterlánc hosszát kapjuk: return(t-s)

21

Page 22: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;int getline(char *s, int n){

int c;

char *t=s;

while(n-- > 0 && (c=getchar())!=EOF && c!='\n')

*t++ = c;

*t='\0';

while(c!=EOF&&c!='\n')

c=getchar();

return(t-s);

}

22

Page 23: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;squeeze

void squeeze(char s[], int c){

int i,j;

for(i=j=0; s[i]!='\0'; i++)

if(s[i]!=c)

s[j++]=s[i];

s[j]='\0';

}

23

Page 24: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;*squeeze

• char *squeeze(char *s, int c)• c karakter törlése az s karakterláncból a saját helyén.

24

Page 25: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*squeeze

main(){char s[]="Ebben vannak n-ek";printf("%s\n",squeeze(s,'n'));getchar();

}

char *squeeze(char *s, int c){char *p,*t;p=s;t=s;while(*p){

if(*p==c) p++;else *s++=*p++;

} *s=0;return(t);

}

25

Page 26: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;*squeeze

char *squeeze(char *s, int c){

char *t, *ment=s;

for(t=s; *s; ++s)

if(*s!=c) *t++=*s;

*t='\0';

return ment;

}

26

Page 27: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;A „klasszikus” atoi

int atoi(char s[]){

int i,n=0,sign=1;

for(i=0;s[i]==' '|| s[i]=='\n' || s[i]=='\t'; ++i);

if(s[i]=='+'||s[i]=='-')

sign=(s[i++]=='+') ? 1 : -1;

for(;s[i]>='0'&&s[i]<='9';++i)

n=10*n+s[i]-'0';

return(sign*n);

}

27

Page 28: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Atoi mutatókkal

int atoi(char *s){

int n=0, sign=1;

for( ; isspace(*s); ++s);

if(*s=='+'||*s=='-')

sign=(*s++=='+') ? 1 : -1;

for( ; isdigit(*s); ++s)

n=10*n+*s-'0';

return(sign*n);

}

28

Page 29: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;atoi

• Eredeti: stdlib.h• Karakterlánc egésszé alakítása• (isspace >> ctype.h)

• Íjuk meg ennek is a mutatós változatát!

29

Page 30: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat char * 02

Készítse el az alább felsorolt, ismert C függvények mutatós változatát! A char * visszatérésű függvények az eredmény címével térnek vissza!• Karakterlánc nagybetűssé alakítása:void strupr(char s[])char *strupr(char *s) továbbá strlwr

• Karakterlánc megfordítása helyben:void strrev(char s[])char *strrev(char *s)

• Karakterlánc feltöltése c karakterrel:void strset(char s[], int c)char *strset(char *s, int c)

30

Page 31: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;strrev (mutatók nélkül)

void strrev(char s[]){int i, j;char kar;for(i = 0, j = strlen(s)-1; i<j; ++i, --j){kar = s[i]; s[i] = s[j]; s[j] = kar;

} }

31

Page 32: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;strrev

s[0] s[1] s[2] s[3] s[4] s[5] s[6] s[7] s[8] s[9]

a b c d x 6 7 8 9 '\0'

[i=0] 9 b c d x 6 7 8 a '\0'

[i=1] 9 8 c d x 6 7 b a '\0'

[i=2] 9 8 7 d X 6 c b a '\0'

[i=3] 9 8 7 6 x d c b a '\0'

32

Page 33: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;String bejárása - mutatók

• char *s="Szoveg";

• for(;*s!='\0'; ++s) printf("%c\n", *s);

vagy röviden:

• for(;*s; ++s) printf("%c\n", *s);

33

Page 34: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

Az strstr() függvény a második karakterlánc elsőbeli első előfordulásának címével tér vissza, ill. NULL mutatóval, ha a második karakterlánc nem található meg az elsőben.int index(char s1[], char s2[]) – char *strstr(char *, char *)

Készítsen char *strstrnext(char *, char *) függvényt, mely ugyanazt teszi, mint az strstr(), de egy static mutató segítségével az első hívás után a második karakterlánc következő elsőbelielőfordulásának címével tér vissza, és ezt mindaddig teszi, míg NULLmutatót nem kell szolgáltatnia.

Feladat - strstr, strstnext

34strnext.c strstr.c

AZ elofordulasai AxxAZxAZxxxAyZ-ben:Megtalaltuk a 3 indexu helytol kezdodoen.Megtalaltuk a 6 indexu helytol kezdodoen.

Page 35: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - titkosítás

Készítsen char* titkositas(char* nyiltszoveg, char* kulcs, int hossz)függvényt, ami a titkosítja a paraméterként kapott nyílt szöveget a második paraméter

kulccsal, majd visszaadja az eredményt. (Az eredmény a nyílt szöveg helyén keletkezik.) A

harmadik paraméter a nyiltszoveg jeleinek száma. A titkosítást úgy végzi, hogy a nyílt szöveg

első betűjének ASCII kódját kizáró vagy kapcsolatba hozza a kulcs első jelének ASCII

kódjával, aztán a nyílt szöveg második jelének kódját hozza kizáró vagy kapcsolatba a kulcs

második jelének kódjával, és így tovább. Ha a nyílt szöveg rövidebb lenne, mint a kulcs,

akkor nem kell a kulcs minden jelét felhasználni. Ha a kulcs rövidebb, mint a nyílt szöveg,

akkor a kulcsnak ismét az első, második, stb. jelét kell használni. Készítsen programot a fv.

kipróbálásához! Ebben olvassa be a nyílt szöveget, majd a kulcsot, aztán jelentesse meg a

titkosított szöveget! Ezt követően a már titkosított szöveget titkosítsa ismét a kulccsal! Ennek

hatására az eredeti nyílt szöveget kell visszakapni. Jelenítse meg ezt is a kimeneten!

Természetesen ebben a programban is csak mutatók használata megengedett, a tömbök

indexelése nem!

35

A nyilt szoveg: JelszoKodolt szoveg: '/7?)A helyreallitott szoveg: JelszoKód: ABCDEF Extra2.c

Page 36: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Mutatótömbök

• Mutatókat tartalmazó tömbök

• Pl. stringeket is tárolhatunk így tömbben• A main() argumentumlistája

36

#include <stdlib.h>

#include <stdio.h>

void ir( int ennyit, char **ezt ){

int n;

for(n=0; n<ennyit; ++n )

printf("%s\n", ezt[n] );

}

main(){

char *tomb[3];

tomb[0]="Szoveg";

tomb[1]="AB";

tomb[2]="xyz";

ir(2, tomb );

getchar();

}A B \0

x y \0 ..

S z o v e g \00xfa02120xfc00c1

0xfc00b1

0xfc0012

* *

[]

Page 37: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;A main() argumentumlistája

• Parancssori argumentumok fogadása• Minden C programban kell lennie egy a programot elindító

függvénynek, mely konzol bázisú alkalmazások esetében a main függvény.

• A paraméterek elhagyhatóak és nem ANSI szabványosak.• Project properties >> Debugging >> Command arguments

#include <stdio.h>int main( int argc, char *argv[] ){

int n;for(n=0; n<argc; ++n)

printf( "%s ", argv[n] );printf("\n");return(0);}

37

Page 38: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;*argv[]

Az argv a paraméter karakterláncokra mutató mutatótömb, ahol az egyes elemek rendre:• argv[0]: A futó program (meghajtó névvel és) úttal ellátott

azonosítójára mutató mutató.• argv[1]: Az első parancssori parameter karakterlancara

mutató mutató.• argv[2]: Az második paraméter karakterlánc kezdőcíme.• argv[argc - 1]: Az utolsó parancssori paraméter

karakterláncára mutató mutató.• argv[argc]: NULL mutató.

38

Page 39: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;A printf utolsó, *argv++ kifejezése

Az argv–t a main paraméterként kapja, tehát csak címmásolat,

vagyis a main–ben akár el is rontható. Az argv típusa char **, és

funkcionálisan a parancssori paraméter karakterláncok kezdőcímeit

tartalmazó mutatótömb kezdetének cime. A rajta vegrehajtott indirekcióval a típus char * lesz, és épp a mutatótömb első elemet

(argv[0]) érjük el. Az utótag ++ operator miatt eközben az argv

mar a második mutatótömb elemre (argv[1]) mutat. Elérjük ezt

is, es mellékhatásként az argv megint előbbre mutat egy

tömbelemmel. Tehát a ciklusban rendre végigjárjuk az összes

parancssori paramétert.

39

Page 40: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Függvény (kód) mutató

• A C nyelvben a mutatóknak két fajtája van:• (adat) objektumra mutató mutatók és

• függvényre (kód) mutató mutatók

void doubleRendez(double tomb[], int meret, int (*kisebb_e)(double a, double b));int kisebb(double a, double b) {

return a < b;}int abszolutKisebb(double a, double b) {

return fabs(a) < fabs(b);}. . .doubleRendez(tomb, 10, kisebb);

40doubleRendez.c

Page 41: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - függvénymutató

• Írjunk függvényt, amely paraméterként kap egy double

elemekből álló tömböt, és rendezi azt! A rendezés szempontja

(növekvő, csökkenő, abszolútérték szerint növekvő stb.) is

legyen a függvény paramétere!

void doubleRendez(double tomb[], int meret, int (*kisebb_e)(double a, double b))

41doubleRendez.c

Page 42: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Dinamikus memóriakezelés

A C fordító a memóriát három részre osztja:

1. heap segment » dinamikus adatterület » dinamikusan,

futásidőben foglalt, változó méretű memóriablokkok

2. stack segment » verem adatterület » lokális objektumok,

függvények paraméterei

3. data segment » elsődleges adatterület » globális objektumok,

konstansok, statikus objektumok

Az stdlib.h fejfájl dinamikus memóriakezelést megvalósító

függvényei: void *malloc(m), void *calloc(a,b), voidfree(void *memória), void realloc(c,m) stb.

42

Heap

Stack

Static / global

Code (text)

Page 43: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

#include <stdio.h>#include <stdlib.h>

int globEredmeny;

int negyzet(int x) {return x*x;

}

int negyzOsszeg(int x, int y) {return negyzet(x + y);

}

void main(){int a = 1, b = 2, *p;globEredmeny = negyzOsszeg(a, b);p = (int*)malloc(sizeof(int));*p = globEredmeny;printf("p ereteke: %d", *p);free(p);

}

Dinamikus memóriakezelés

43

Heap

Stack (verem)

Static / global

Code (text)

Global

Stack

Heap

Forrás: mycodeschool

int globEredmeny;

main()a, b

negyzOsszegx, y

negyzetx

p =

(int*)malloc

(sizeof(int))

main()a, b

negyzOsszegx, y

main()a, b

free(p);

Page 44: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;void *malloc(m), void *calloc(a,b)

• A malloc-nak egy paramétere van: hány bájtot szeretnénk

lefoglalni. Ezzel szemben a calloc-nak két paramétere van,

és a kettő szorzata adja a kívánt bájtszámot. • A malloc által lefoglalt memóriaterület „memóriaszemetet”

tartalmaz, azaz a dinamikusan lefoglalt változó kezdeti értéke

bármi lehet, ahogyan ezt az egyszerű, nem dinamikus változóknál is megszoktuk. A calloc ezzel szemben a

lefoglalt terület minden bájtját kinullázza. • NULL-lal tér vissza hiba esetén.

44

Page 45: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;void free(void *memória), void realloc(c,m)

• A free a malloc által lefoglalt területet szabadítja fel. Első

paramétere az a mutató, amit még a malloc adott vissza.

• A realloc a lefoglalt terület méretét változtatja meg. Első

paramétere a memóriacím, második pedig az új méret.

45

Page 46: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;memcpy, memccpy

• void memcpy(void *cél, const void *forrás, size_t db);

a memóriaterület tartalmát másolhatjuk át

• void memccpy(void *cél, const void *forrás, int keres, size_t db);

a memóriaterület tartalmát másolhatjuk át, adott méret vagy

hatójel alapján

46

Page 47: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;memmove, memset

<string.h>• void *memmove(s, ct, n)

A memmove hasonló a memcpy függvényhez, de egymást

átfedő objektumok esetén is használható.

• void *memset(s, c, n)A memset elhelyezi a c karaktert az s első n karakterében és

visszatérési értéke az s mutatója.

47

Page 48: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Figyeljünk az érvénytelen mutatókra!

Súlyos és veszélyes programozási hiba az érvénytelen mutatók használata, például egy

free() parancs után. Elképzelhető, hogy elsőre működik a program, mert a felszabadított

memóriaterületen még megtalálható a helyes érték.

Például hibás kódrészlet:

char *fuggveny() {char c = 'a';return &c; // hiba!

}

char *p = fuggveny(); // hiba!

48

Page 49: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;sizeof

A sizeof egyoperandusos magas prioritású művelet, mely az

operandusa tárolásához szükséges memória mennyiségét

szolgáltatja bájtban.

• sizeof(egyoperandusos-kifejezés) pl. sizeof(tomb)• sizeof(típusnév) pl. sizeof(int)

Az egyoperandusos kifejezés típusát a fordító a kifejezés kiértékelése

nélkül határozza meg, azaz ha az operandus tömbazonosító, az egész

tömb bájtokban mért helyfoglalásához jutunk.

49

Page 50: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;2d tömb indexelése

int tomb2d[2][4]={{1,2,3,4},{5,6,7,8}};

Indexelés: tomb2d[i][j] máshogy:

• *(tomb2d[i] + j)• (*(tomb2d + i))[j]• *((*(tomb2d tomb2d+ i)) + j)• *(&tomb2d[0][0] + 4*i + j)

50

1 2 3 4 5 6 7 8

1 2 3 4

5 6 7 8

A memóriában, sorfolytonosan:

Tömbreprezentáció:

Page 51: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - dinamikus mátrix

• Allokáljon memóriát egy 𝑛 𝑥 𝑛 méretű int típusú

adatokat tartalmazó mátrix számára, a főátlót töltse

fel egyesekkel, a többi elem legyen nulla. Jelezze is ki

az értékeket.

• Főátlónak a bal felső és a jobb alsó sarkot összekötő

átlót hívjuk.

A példa 𝑛 = 5 esetét mutatja.

51dinmatrix01.c

'dinmtx' elemei:1 0 0 0 00 1 0 0 00 0 1 0 00 0 0 1 00 0 0 0 1

Page 52: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - 2d dinamikus tömb

• Írjon olyan függvényt, amely cím szerint átvett paraméterben adja

vissza a lefoglalt 2D dinamikus tömbre mutató pointert!

void foglal(float ***ptomb, int szeles, int magas)

• Figyeljünk arra, ha a változó típusa float **, akkor a címének

típusa float ***, így cím szerinti paraméterátadásnál is így kell

használni.

52dinmatrix02.c

Page 53: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - 2d dinamikus tömb megoldás

void foglal(float ***ptomb, int szeles, int magas) {float **uj;int y, z;uj = (float**)malloc(magas * sizeof(float*));for (y = 0; y < magas; ++y){

uj[y] = (float*)malloc(szeles * sizeof(float));for(z = 0; z < szeles; ++z){

uj[y][z] = (float)(y + z);//printf("%.1f\n", uj[y][z]);

}}*ptomb = uj; // *ptomb >> a float** típusú változó!

}

53

Page 54: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - Mátrix elemei és címeik

54

'dinmtx' elemei (es cimeik):

dinmtx[0]: (00825AB8)[0][0]=1 (0082A748) [0][1]=2 (0082A74C) [0][2]=3 (0082A750)

dinmtx[1]: (00825ABC)[1][0]=4 (0082A790) [1][1]=5 (0082A794) [1][2]=6 (0082A798)

dinmtx[2]: (00825AC0)[2][0]=7 (0082A7D8) [2][1]=8 (0082A7DC) [2][2]=9 (0082A7E0)

dinmatrix03.c

Page 55: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Random - Véletlenszám

#include <stdio.h>#include <time.h>#include <stdlib.h>

#define MAX 20

void main(){int r = 0, i;srand(time(NULL));for(i=0; i<20; i++){

r = (rand() % MAX);printf("%d\n", r);

}getchar();

}

55

Álvéletlen számok

(pseudo-random numbers)

Page 56: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Random - Véletlenszám

A véletlenszám-generátor használata: program elején inicializálni kell

(srand) egyszer, és utána a rand() ad egy véletlen számot. A %100

hatására 0..99 között lesz, ehhez 1-et adva kapjuk az 1..100

tartományt. A működéshez a stdio.h, time.h, stdlib.h headerek

szükségesek.

srand(time(NULL));

r = rand()%100 + 1;

56

Page 57: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - mátrix összeadás

Készítsen programot két mátrix összeadására! A mátrixoknak

foglaljon helyet a memóriában! A mátrixok mérete azonban

csak futás időben dől el. A számok beolvasásához felhasználható az int getint(int *) függvény, de feltétlenül

lássuk el minimális inputellenőrzéssel!

57mtx.c

Page 58: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - Bűvös mátrix (magic square)

Olyan (ált. 1 és n2 közötti) egész számokat tartalmazó

négyzetes mátrix, melynek minden sorösszege, minden oszlop

összege, főátlójában és mellékátlójában lévő számok összege

azonos. https://en.wikipedia.org/wiki/Magic_square

58

8 1 63 5 74 9 2

Buvos matrix? Igen

117 34 115104 1 6327 49 29

Buvos matrix? Nem

buvosMatrix.c

Page 59: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - Sudoku generálás

Generáljunk egy 9 x 9-es tömböt, úgy, hogy 1-től 9-ig legyenek benn számok, de tetszőleges sorban, oszlopban mindegyik szám csupán egyszer forduljon elő.Megjegyzés: a játékban ennél több szabály van.Megoldható *p és **p megvalósítással.

59

1 2 3 4 5 6 7 8 92 3 4 5 6 7 8 9 13 4 5 6 7 8 9 1 24 5 6 7 8 9 1 2 35 6 7 8 9 1 2 3 46 7 8 9 1 2 3 4 57 8 9 1 2 3 4 5 68 9 1 2 3 4 5 6 79 1 2 3 4 5 6 7 8

3 9 1 4 2 7 6 5 84 1 2 5 3 8 7 6 95 2 3 6 4 9 8 7 16 3 4 7 5 1 9 8 27 4 5 8 6 2 1 9 38 5 6 9 7 3 2 1 49 6 7 1 8 4 3 2 51 7 8 2 9 5 4 3 62 8 9 3 1 6 5 4 7

7 4 5 8 6 2 1 9 3

4 1 2 5 3 8 7 6 9

1 7 8 2 9 5 4 3 6

6 3 4 7 5 1 9 8 2

9 6 7 1 8 4 3 2 5

8 5 6 9 7 3 2 1 4

3 9 1 4 2 7 6 5 8

5 2 3 6 4 9 8 7 1

2 8 9 3 1 6 5 4 7

sudoku1d.c sudoku2d.c

Page 60: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;2D tömb megvalósítások

1. Sorfolytonosan

2. Soronkénti foglalás

3. Leképezés és

mutatótömb

"jagged array"

60

Page 61: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Soronkénti foglalás egydimenziós mutatótömbbel

#include <stdio.h>#define MERET 3void main(){char* muttomb[MERET] = {"Egy","két","há"}; int i;printf("'muttomb' elemei: \n");for (i = 0; i<MERET; i++)printf("%s (%p) (%p)\n", muttomb[i], &muttomb[i], &muttomb[i][0]);

printf("\n");getchar();

}

61

'muttomb' elemei:Egy (0114FE18) (01345858)két (0114FE1C) (0134585C)há (0114FE20) (01345860)

Memóriában:0x0114FE18: 01345858 0134585c 01345860 cccccccc0x01345858: 00796745 0074e96b 0000e168 20756d27 0x01345858: Egy.két.há..0x0134585C: két.há.....x0x01345860: há.....xxxxx

Page 62: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat valós számok tömbbe, mutatókkal

Készítse el a PELDA24.C-hez hasonlóan a valós számok

tömbbe olvasását és visszaírását!Az int getint(int*) függvény int getfloat (float *)-ra

változtatandó! Az int bufp; lecserélendő char *bufp;-re!

Tegyünk legalább annyi inputellenőrzést a getfloat-ba, hogy

legalább egy numerikus karakter meglétét megkövetelje, ill.

konvertálhatatlan karakterek esetén ürítsük ki a bemeneti

puffert a legközelebbi fehér karakterig!

62

Page 63: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• Összetett adattípus, mint a tömbök, de nem csak egyféle

típus alkothatja őket

• Változók csoportjának egyszerűbb kezelése

• Lehetőségek:» hozzárendelés (másolás)

» átadhatók függvénynek paraméterként

» lehet függvény visszatérési értéke

» képezhető méretük (sizeof) és címük (&)

» nem lehetséges: összehasonlítás (csak tagonként)

» struktúratag szinte bármiből lehet

Struktúrák

63

Page 64: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Struktúrák

#include <stdio.h>

struct Pont{

int x;

int y;

int z;

char nev[32];

};

void main(){

struct Pont p1, p2;

p1.x=8;

p1.y=5;

}

64

A ; nem véletlen a struktúrák után.

Page 65: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Typedef

#include <stdio.h>

typedef int egesz;

void main(){

egesz e = 42;

printf("e=%d\n", e);

}

65

Új típust a typedefkulcsszóval vezethetünk be.Az egesz típus közvetlenül az

int típusból származik.

Persze ez így még nem túl

hasznos.

Page 66: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Typedef és struktúra

#include <stdio.h>

struct Pont{

int x;

int y;

int z;

};

typedef struct Pont pont;

int kiir( pont *p ){

printf("x=%d\ny=%d\nz=%d\n",p->x, p->y, p->z);

}

void main(){

pont p1, p2;

p1.x=1;

p1.y=42;

p1.z=84;

kiir(&p1);

}

66

A Pontegy struktúra, a pont pedig típusdefiníció.A ; nem véletlen a struktúrák

után.

typedef struct Pont {

int x;

int y;

int z;

} pont;

Elhagyható –

névtelen

struktúra.

Page 67: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Struktúrák

67

typedef struct { //egy pont a síkbandouble x;double y;

} Pont;

typedef struct { //szakasz két pont köztPont eleje; Pont vege;

} Szakasz;

typedef struct { //középpont és sugárPont kozeppont;double sugar;

} Kor;

Page 68: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Structure dereference operator

Structure dereference (röviden: nyíl) operátor jelentése a mutató által mutatott struktúra adattagja. Egyrészt dereferál, másrészt adattagot is kiválaszt, így rövidebb.

(*p).adattag vagy rövidebb jelöléssel:p->adattag

A pont "." adattag kiválasztó operátor nagyobb precedenciájú, mint a "*" índirekció operátor. Ezért is kell zárójelezni, a nyíl operátor erre ad könnyebb módot.

68

Page 69: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - szakasz

Írjon programot, mely a jelzett

adatstruktúrákat használja. Egy double szakaszHossza(Szakasz *sz)prototípusú függvény visszatérési értékeként számolja ki a megadott szakasz hosszát!

69Megoldás: szakasz.c

typedef struct{double x;double y;

}Pont;//szakasz két pont közttypedef struct{

Pont eleje;Pont vege;

}Szakasz;

Page 70: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - osztálytárs

Írjon programot, mely a jelzett adatstruktúrákat használja. A feladatban tartsuk számon, hogy az osztálytársak kit tartanak a legjobb barátjuknak. Írjon függvényt, mely kiírja, hogy az adott személy barátsága kölcsönös-e. Továbbá listázza az összes személy barátait.

70Megoldás: osztalytars.c

typedef struct{

char nev[32];

int legjobbbarat;

} diak;

// strukturákból alló tömb

diak osztalytarsak[10];

// kölcsönös-e a barátság

int kolcsonos(int szemely){

if (osztalytarsak[osztalytarsak[szemely].legjobbbarat].legjobbbarat

= szemely)

return 1;

else

return 0;

}

Page 71: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - Dinamikus tömb 02

Írjon programot, amely bekéri, egy sokszög csúcsainak számát,

ezután pedig egyesével a csúcsok koordinátáit! A koordinátákat

egy struktúrában tárolja, melynek dinamikusan foglaljon memóriát. Inputellenőrzés! (lebege, egesze)

typedef struct{

double x, y;

} Pont;

Pont *sokszog;

71

A struktúra méretét megadja az n*sizeof(Pont)

kifejezés.

sokszog=(Pont*)malloc(n*sizeof(Pont));

Megoldás: dinstrukt02sokszog.c

Page 72: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - Dinamikus tömb 03

Írjon programot, amelyben egy int valogat(double *eredeti, int meret, double **ujtomb, int *ujmeret)

függvény egy paraméterben kapott double tömbből kiválogatja

az átlagnál kisebb értékeket, és egy újonnan lefoglalt dinamikus

tömbbe rakja azokat! Az új tömb címével és méretével térjen

vissza cím szerint átadott paraméterben! A visszatérési érték

legyen IGAZ, ha sikerült a művelet, és HAMIS, ha nem.Megoldás: dinstrukt03valogat.c

72

Page 73: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

Hasonlít a struktúrákra, de a tagok azonos tárcímen kezdődnek » az uniót címző

mutató egyben valamennyi tagot is címzi (de a mutató típusok eltérőek lehetnek)

Unió tárigénye = legnagyobb tag tárigénye

Uniók

73

#include<stdio.h>

void main() {

union byte {

unsigned negy; unsigned short ket[2];

unsigned char egy[4];

} adat = { 0x0103070Ful };

printf("'adat' cime: %p, merete: %lu byte\n"

"'adat.negy' cime: %p, merete: %lu byte, erteke: %08x\n"

"'adat.ket' cime: %p, merete: %lu byte, ertekei: %04x; %04x\n"

"'adat.egy' cime: %p, merete: %lu byte, "

"ertekei: %02x; %02x; %02x; %02x\n", &adat, sizeof(adat),

&adat.negy, sizeof(adat.negy), adat.negy,

&adat.ket, sizeof(adat.ket), adat.ket[0], adat.ket[1],

&adat.egy, sizeof(adat.egy), adat.egy[0], adat.egy[1],

adat.egy[2], adat.egy[3]);

}

'adat' cime: 0037FD04, merete: 4 byte

'adat.negy' cime: 0037FD04, merete: 4 byte, erteke: 0103070f

'adat.ket' cime: 0037FD04, merete: 4 byte, ertekei: 070f; 0103

'adat.egy' cime: 0037FD04, merete: 4 byte, ertekei: 0f; 07; 03; 01

Page 74: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Linked list (láncolt lista)

• Olyan önhivatkozó adatszerkezet, ahol az egyes elemek

láncba vannak fűzve azáltal, hogy tárolják a soron következő

elem címét.

typedef struct elem{ //egy listaelem

unsigned adat; //nem csak egy elem lehet

struct elem *kov; //itt még kell a struct

} elem;

74

Page 75: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Egyszerű láncolt lista

typedef struct elem {

char nev[100]; //név

unsigned eletkor; //életkor

struct elem *kov;

} elem_t;

elem_t *kezd;

kezd = malloc(sizeof(elem_t));

kezd->eletkor = 19;

kezd->kov = malloc(sizeof(elem_t));

kezd->kov-> eletkor = 88;

75

Megjegyzés:

A typedef segítségével létrehozunk egy

rövidebb nevet, a struktúrán belül mégis

a struct kulcsszót kell használni, hiszen

ott még nem létezik az alternatív név.

Ebben az esetben tehát nem

használhatjuk a névtelen struktúrát.

Page 76: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Láncolt lista bejárása

1. elem címe: eleje2. elem címe: eleje->kov

(*eleje).kov3. elem címe: eleje->kov->kov

(*(*eleje).kov).kov4. elem címe: eleje->kov->kov->kov

(*(*(*eleje).kov).kov).kov

760xcc6

0xcc1

0xcc6 0xcc1

0xcb0

0xcb0

0xcca

0xcca

NULL

1 2 3 4ListaElem *eleje

Page 77: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;A lista bejárása

ListaElem *iter;

for (iter = eleje; iter != NULL; iter = iter->kov)

printf("%d ", iter->szam);

77

Nézzünk erre egy példát!lancolt00alap.c

0xcc60xcc1

0xcc6 0xcc1

0xcb0

0xcb0

0xcca

0xcca

NULL

1 2 3 4ListaElem *eleje

ListaElem *iter

Page 78: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

• Írjon rövid C programot, amely létrehozza a

jelzett adatstruktúrában a láncolt listát, majd

rendre kiíratja az elemeit.

Feladat – láncolt lista létrehozás, bejárása

78lancolt00alap.c

typedef struct Lista {int adat;struct Lista *kov;

}Lista;

[1] [0066A820] [0066A7D8][17] [0066A7D8] [0066A790][12] [0066A790] [0066A748][14] [0066A748] [00665AB8][8] [00665AB8] [00000000]

printf("[%d]\t[%p]\t[%p]\n", iter->adat, iter, iter->kov);

Page 79: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• Törlés a lista elejéről:

» az előtte lévő mutató kov elemét az utána lévőre

állítjuk

» felszabadítjuk a törlendőt

• Törlés algoritmusa a lista belsejéből:

» megkeressük a törlendő elemet

» az előtte lévő mutató kov elemét az utána lévőre

állítjuk

» felszabadítjuk a törlendőt

Törlés láncolt listából

79

Page 80: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Törlés tömbből/láncolt listából

80

[0] [1] [2] [3] [4] [5]

[0] X[1] [2] [3] [4]

Tömb

Láncolt

lista

És ha ez sokkal több elem?

Műveletigény?

Műveletigény?

Page 81: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• tömbök előnye: » a sorfolytonos tárolás miatt közvetlenül

címezhető

» gyors adatelérés

• tömbök hátránya:» lassú átméretezés

» nem ideális beszúrás/törlésintenzív

feladatokra

• láncolt listák előnye:» gyors átméretezés: beszúrás, törlés

• láncolt listák hátránya:» nincs közvetlen elérés

Tömbök/láncolt listák

81

0 1 2 3 4

0 1 2 3

Page 82: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

• Írjon programot, amely a beolvasott

karakterláncokat (stringeket) láncolt listában

tárolja el. Törölje ki belőle azokat, amelyek

pontosan öt betűből állnak.

• Figyeljünk, arra, ha az első elemet szeretnénk

törölni, a kezdőcím is megváltozik (sőt ha az első

N darabot, akkor is).

• Gondoljuk át, hogy nézne ki az algoritmus

láncolt listák helyett, többdimenziós tömbökkel.

Feladat - törlés láncolt listából

82Megoldás: lancolt01torol.c

typedef struct Szo {char szo[MAX+1];struct Szo *kov;

} Szo;

Page 83: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Beszúrás a lista elejére

Amit tudnia kell a függvénynek:

• a lista elejére mutató pointert

• az új, eltárolandó adatot

Az algoritmus:

• az új elemnek memóriát allokálni, adatait beállítani, a "kov" lesz az új lista

elejére mutató pointer

• üres lista esetén az új elem egymaga lesz a lista

• meg kell tudnia változtatni az "eleje" mutatót, ezzel tér vissza

Lista *lisE = NULL;lisE = listaElejere(lisE, 5);lisE = listaElejere(lisE, 10);

83

Page 84: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

//lista elejére tesz számokat

Lista *listaElejere(Lista *eleje, int adat) {

Lista *uj=(Lista*)malloc(sizeof(Lista));

uj->kov = eleje;

uj->adat = adat;

eleje = uj;

return eleje;

}

Beszúrás a lista elejére

84

0xcc60xcc1

0xcc6 0xcc1

0xcb0

0xcb0

0xcca

0xcca

NULL

1 2 3 4

Lista *eleje

0xcc10xcb0 0xcca NULL

2 3 4

Lista *eleje

0xcc1

Lista *uj

0xcb0 0xcca

Page 85: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

Amit tudnia kell a függvénynek:

• a lista elejére mutató pointert

• az új, eltárolandó adatot

Az algoritmus:• az új elemnek memóriát allokálni, adatait beállítani, a "kov" értéke most NULL lesz

• üres lista esetén az új elem egymaga lesz a lista

• végigiterálunk a listán és megkeressük az utolsó elemet• az utolsó elem "kov" mutatóját beállítjuk az új elem címére

Lista *lisV = NULL;

lisV = listaVegere(lisV, 5);

lisV = listaVegere(lisV, 10);

Beszúrás a lista végére

85

0xcc10xcb0 0xcca NULL

2 3 4

0xcc1 0xcb0 0xcca

0xcc10xcb0 0xcca

2 3 4

0xcc1

NULL

0xcb0 0xcca 0xc00

0xc00

5

Page 86: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Beszúrás a lista végére

//lista végére tesz számokatLista *listaVegere(Lista *eleje, int adat) {

Lista *mozgo, *uj;uj=(Lista*)malloc(sizeof(Lista));uj->adat = adat;uj->kov = NULL;if (eleje == NULL)//üres lista?

return uj;for(mozgo = eleje; mozgo->kov!=NULL; mozgo=mozgo->kov)

; //üres ciklus, megkeresi az utolsó elemetmozgo->kov = uj;return eleje;

}

86

Page 87: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - láncolt lista megfordítás

• Fordítsunk meg egy listát az elemei átláncolása által. Írjon

programot, mely számokat olvas be, és kiírja a keletkező listát

eredeti sorrendjében (és ezáltal a számokat eredeti

sorrendjükben), továbbá kiírja a megfordítottat is.

• Mindig a lista elejéről veszünk el egy elemet, majd a

megfordított lista elejére betesszük azt, így a lista megfordul.

Végül az eredeti lista elfogy, amint ez megtörténik, a

megfordított lista kész.

87Megoldás: lancolt02megfordit.c

Forrás: A programozás alapjai - Pohl László, Budapest, 2010

Page 88: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Láncolt lista megfordítása

Szam *listaMegfordit(Szam *lista) {Szam *eredeti=lista;Szam *megforditott=NULL;while (eredeti!=NULL) {Szam *atrakott=eredeti; Szam *kovetkezo=eredeti->kov;atrakott->kov=megforditott;//új elejére bemegforditott=atrakott;eredeti=kovetkezo;//régiből kihagy}return megforditott;}

Mindig a lista elejéről veszünk el egy elemet, majd a megfordított lista elejére betesszük azt, így a lista

megfordul. Végül az eredeti lista elfogy, amint ez megtörténik, a megfordított lista kész.

88

1

2

3

eredeti

megfordított

átrakott következő

12

3

Page 89: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• Doubly linked list

• Hátrafelé és előrefelé is be tudjuk járni

» Az egyszeresen láncoltat csak előre

• Két plusz "strázsa" elem, amelynek nem

tartalmaznak hasznos adatot, tehát a

hasznos adatok listája az eleje ("első") strázsa

utáni elemtől a vége ("utolsó") elemig tart.

Kétszeresen láncolt lista

89

typedef struct elem{

unsigned adat;

struct elem *kov, *elozo;

} elem;

Page 90: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• queue, FIFO » first in, first out» pl. producer-consumer (termelő-

fogyasztó probléma)

• stack, LIFO » last in, first out» pl. syntax parsing

• circular list» pl. round-robin

További listás megvalósítások

90

Page 91: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;State machine - állapotgép

• Az állapotgép egy gyakran használt tervezési minta (design

pattern),

• A lényege, hogy az adott alrendszer csak egy állapotban

lehet egyszerre, ebből az átmenetek és az egyes állapotok

tevékenységei pontosan definiáltak.

• Megadható állapot és tevékenységtáblás, UML diagram és

nem szabványos módokon.» http://en.wikipedia.org/wiki/Finite-state_machine

» http://en.wikipedia.org/wiki/UML_state_machine

91

Page 92: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Szövegfeldolgozó állapotgéppel

• Tegyük fel, hogy nem tudjuk, milyen hosszú egy sor» nem olvashatunk tömbbe egy sort

» karakterenként olvassunk

• Szűrjük ki a /*-gal kezdőtő és */-ig tartó kommenteket

Szöveg* valami /*komment ** és /*/ hh /*a*/ szöveg

92Forrás: A programozás alapjai - Pohl László, Budapest, 2010

Page 93: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

4 állapotú state machine implementáció

//state machine - állapotgép

#include <stdio.h>

typedef enum {normal,komment,cs_var,p_var}

allapotok;

int main(void){

int c;

allapotok a = normal;

//CTR+Z-ig

while((c=getchar())!=EOF){

switch (a){

case normal:

if(c!='/')putchar(c);

else a = cs_var;

break;

case cs_var:

if(c=='*') a = komment;

else{

putchar('/');

if(c!='/'){

putchar(c);

a=normal;

}

}

break;

case komment:

if(c=='*') a = p_var;

break;

case p_var:

if(c=='/') a = normal;

else if(c!='*') a = komment;

break;

}

}

}

93Forrás: A programozás alapjai - Pohl László, Budapest, 2010

Page 94: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Komment /* */ szűrő

Állapot ’*’ ’/’ egyéb

normál normál csillagra vár normál

csillagra vár megjegyzés csillagra vár normál

megjegyzés perre vár megjegyzés megjegyzés

perre vár perre vár normál megjegyzés

94

Állapot ’*’ ’/’ egyéb

normál másol nem másol másol

csillagra vár nem másol előző ’/’ kiírása,

nem másol

előző ’/’ kiírása,

másol

Állapottábla

Tevékenységtábla

Forrás: A programozás alapjai - Pohl László, Budapest, 2010

Page 95: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Komment /* */ szűrő

95

normal cs_var megj p_var

egyéb, '*' egyéb, '/'

'*'

'/'

'/' '*'

egyéb egyéb

'*''/'

Az implementációba be lehet tenni egy plusz állapotot - végállapotot -, amibe bármikor elérhetünk EOF hatására.

Page 96: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Helyi beállítások

• locale.h fejfájl ANSI/ISO szabványos típusok, szimbolikus állandók

és függvények használatához.

• Ország, nyelv, dátum formátuma, pénznem, stb. Ezeket az

összetevőket helyi kategóriáknak nevezzük. Szimbolikus állandók, a

program helyi információjának mely részéről van szó.

• A hely bizonyos vonatkozásait a könyvtári rutinok automatikusan

kezelik. Például: strcoll, strxfrm.

• Más vonatkozások viszont kívül esnek a rutinok hatáskörén. Például a

(hiba)üzenetek nyelve.

• Alapértelmezés a "C" hely, és programindításkor.

char *setlocale(int kategoria, const char *locale);

96

Page 97: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Helyi beállítások

• Francia Kanadához ANSI alapértelmezett kódlapot állít.setlocale(LC_ALL, "French_Canada.ACP");

• Francia Kanadához OEM alapértelmezett kódlapot állít.setlocale(LC_ALL, "French_Canada.OCP");

• Alapértelmezés:setlocale(LC_ALL, "C"); setlocale(LC_ALL, NULL);

• Az operációs rendszer értékei:setlocale(LC_ALL, "");

• A következő, két setlocale hívás funkcionálisan ekvivalens:setlocale(LC_ALL, "English");setlocale(LC_ALL, "English_United States.1252");

97

Page 98: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• A struct lconv tagjai leírják, hogyan kell formázni a

numerikus és a pénzügyi értékeket, mint például a

nemzetközi pénznem szimbólumát, a decimális pontot stb.

• A struct lconv *localeconv(void) az aktuális helyi

numerikus és pénzügyi beállításokat egy statikus lconv

struktúrában helyezi el, és visszaadja ennek címét.

• A setlocale kategória paramétere nem csak LC_ALL,

hanem többek között LC_TIME (dátum és idő beállításokra

hat) vagy LC_MONETARY (pénzügyi beállításokra hat) is lehet.

Helyi beállítások

98

Page 99: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Helyi beállítások

//Alapbeállításokprintf("\nHely: %s\n", setlocale(LC_ALL, NULL));printf("Szam: %.2f\n\n", atof("3.14")); //Tizedespont

//Alapértelmezett hely beállításastrcpy(puff, setlocale(LC_ALL, ""));printf("\nHely: %s\n", puff);printf("Szam: %.2f\n\n", atof("3,14")); //Tizedesvessző// Tizedespont és pénznem karakter:plconv = localeconv();printf("Nem penzugyi decimalis pont: %s\n", plconv->decimal_point);printf("Penznem szimbolum: %s\n", plconv->currency_symbol);

// A hely visszaállítása C környezetre:setlocale(LC_ALL, "C");

99Elérhető: helyi01.c

Page 100: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Karakterkódolás, ékezetek

• Az egybájtos karakterkódolások:» ASCII » 128 karakter, 7 bit (2^7 = 128)

» Latin-1 » másnéven ISO8859-1 » az első 128 ugyanaz, mint az ASCII, de,

utána még 96 betűt használ (160-255 tartományban), így is belefér az

egy bájtba (2^8 = 256) » nincs benn magyar ő és ű csak û és õ

» Latin-2 » hasonló a Latin-1-hez, de ebben a magyar ő és ű is

megtalálható

» Windows-1250 » ez hasonlít a Latin-2-hez, többek közt a Windows

szöveges fájok is használják, konzolos alkalmazásoknál előfordul,

célszerű ezt használnunk C programok esetében.

» OEM-852 » konzolban szintén előfordulhat (a, de nem hasonlít a Latin-

2-höz

100

Page 101: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Karakterkódolás, ékezetek

• A többbájtos karakterkódolások:

» Unicode » Az első 128 karaktere ugyanaz, az ASCII-é, de több, mint 120000

karaktert tartalmaz a világ majdnem összes nyelvén. 2 bájtos, így már nem

fér bele a char adattípusba, egybájtosról viszonylag könnyen átalakítható

kódolás, de vissza már kevésbé, hiszen egy Unicode karakter nem biztos,

hogy létezik pl.: Latin-2-ben. További probléma, hogy a 2 bájtot nem

minden architektúra ugyanabban a sorrendben tárolja. Ezt a BOM (byte

order mark) hivatott jelezni, mely vagy 0xFEFF vagy 0xFFFE.

(C90: wchar_t típus » 16 biten kódolja a karaktereket)

» UTF-8 » Változó méretű karakterkódolás, 1 bájtos egységeket használ, így

nem csak sorrendben, de tényleges bináris kódban is kompatibilis az ASCII-

vel, hiszen az egy bájtba beleférő értékeket egy bájton is tárolja.

101

Page 102: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• A magyar nyelvű Windowsban a programok nagy része Windows-1250 karakterkódolást használ, ez a Latin-2-vel

sok hasonlóságot mutat.

Ajánlott beállítások Windows környezetre

102

• Első lépésként a Visual Studio-

ban át kell állítanunk a forrásfájl

kódlapját (File » Advanced Save

Options)

• Ezután a konzol ki és bemeneti

kódlapját kell átállítani. (Nem

szabványos, Windows specifikus)

#if defined(WIN32) || defined(_WIN32)

#include <windows.h>

#endif

#if defined(WIN32) || defined(_WIN32)

SetConsoleCP(1250);

SetConsoleOutputCP(1250);

#endif

Page 103: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h>

#if defined(WIN32) || defined(_WIN32)

#include <windows.h>

#endif

void main() {

struct lconv *plconv; char puff[256];

strcpy(puff, setlocale(LC_ALL, NULL)); plconv = localeconv();

// Beállítások nélkül

printf("\nHely: %s\n", puff);

printf("Nem pénzügyi decimális pont: %s\n", plconv->decimal_point);

printf("Árvíztűrő tükörfúrógép\n\n");

// Op.rendszer által használt nyelvi környezet

strcpy(puff, setlocale(LC_ALL, "")); plconv = localeconv();

printf("Hely: %s\n", setlocale(LC_ALL, puff));

printf("Nem pénzügyi decimális pont: %s\n", plconv->decimal_point);

printf("Árvíztűrő tükörfúrógép\n");

printf("Pénznem szimbólum: %s\n", plconv->currency_symbol);

// A konzolablak kódlapjának beállítása (out és in)

#if defined(WIN32) || defined(_WIN32)

SetConsoleCP(1250); SetConsoleOutputCP(1250);

#endif

printf("Gépeljen szöveget:\n\n"); getline(puff, 255);

printf("A begépelt szöveg: [%s]", puff);

getchar();

}

Helyi beállítások és ékezetek

103Elérhető: helyi02.c

Hely: CNem pÚnz³gyi decimßlis pont: .┴rvizt¹r§ t³k÷rf·r¾gÚp

Hely: Hungarian_Hungary.1250Nem pénzügyi decimális pont: ,Árvíztűrő tükörfúrógépPénznem szimbólum: HUFGépeljen szöveget:

AbcÁÉŰőöA begépelt szöveg: [AbcÁÉŰőö]

Feltételezzük a magyar Windows

operációsrendszert

Page 104: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Magas szintű bemenet, kimenet

• Absztrakt módon, fájlok és eszközök (billentyűzet, képernyő,

nyomtató, stb.) rugalmas, hasonló módon történő független kezelése ún. folyamok (stream) segítségével.

104

Page 105: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Fájlkezelés

• Az stdio.h-ban megadott FILE* típusú pointerrel és függvényekkel.

FILE *fp;

• Megnyitás módja: írás (w) v. olvasás (r), szöveges (t) v. bináris (b), hozzáfűzés (a)

írás és olvasás (w+)

fp=fopen("t.txt", "wt");

• Az fopen() visszatérési értéke: hivatkozás a nyitott fájlra.

Sikertelen megnyitásnál értéke: NULL pointer – ezt ellenőrizni kell.

if (fp == NULL)

printf("Nem sikerült megnyitni!");

105

Page 106: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;fopen - fclose

FILE *fopen(const char *fajlazon, const char *mod);

• A függvény megnyitja a fajlazonnal megnevezett fájlt, és folyamot

kapcsol hozzá. Visszaadja a fájlinformációt tartalmazó FILEstruktúrára mutató pointert, mely a rákövetkező műveletekben

azonosítani fogja a folyamot, ill. NULL mutatót kapunk tőle, ha a

megnyitási kísérlet sikertelen volt.

• Az első paraméter legfeljebb FILENAME_MAX méretű karakter lehet.

• Lezáráshoz: int fclose(FILE *fp) - 0-t ad vissza siker esetén;

EOF-ot, ha nem sikerült lezárni

106

Page 107: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Fájlok kezelése

Szöveges• 48 65 6c 6c 6f 2c 20 76 69 6c 61 67 21 0d0a 30 0d 0a 31 0d 0a

• Hello, vilag!01

• fgets, fgetc, fscanf...

107

Bináris

• 6c cc cc cc 55 8b ec8b 45 0c 83 f8 04 77 23 8b 0c 85 00 80 c5

• lÌÌÌU;>ì-ƒø.w#å4 €Å

• fread, fwrite ...

Page 108: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Szöveges fájlok

• A szövegfájlokat az fprintf()-fel és az fscanf()-fel lehet kezelni. Ezeknek első

paramétere a megnyitott fájl, a folytatás pedig ugyanúgy van, mint printf()-nél és

az scanf()-nél.

• Egyes rendszerek máshogy jelzik a szövegfájlokban a sorok végét

('\n'). Windowson két bájt, CR LF (0x0D 0x0A), Unixokon csak LF (0x0A), a fájlvég

karakter pedig 0x1A.

48 65 6C 6C 6F 2C 20 76 69 6C 61 67 21 0D 0A 30 0D 0A 31 0D 0A 1A

Hello, vilag!x0Dx0A 0x0Dx0A1x0Dx0Ax1A

108

Page 109: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Bináris fájlok

• fp=fopen(nev, "…b")• fread(void *ptr, size_t elem_meret, size_t elem_szam, FILE

*a_file);• fwrite(const void *ptr, size_t elem_meret, size_t elem_szam,

FILE *a_file);

• Lemezre történő kimenet esetén a folyam a sorlezáró '\n'karaktert "\r\n" karakter párral (CR-LF) helyettesíti.

Megfordítva: lemezes bemenetnél a CR-LF karakter párból

ismét LF karakter lesz. Ezt nevezzük transzlációnak.

• Ez csak szöveges fájloknál megy végbe binárisnál nem.

109

Page 110: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Pozícionálás

A folyamokat rendszerint szekvenciális fájlok olvasására, írására

használják. A magas szintű bemenet, kimenet a fájlt bájtfolyamnak tekinti, mely a fájl elejétől (0 pozíció) indul és

a fájl végéig tart. A fájl utolsó pozíciója a fájlméret-1. Az

adatátvitel mindig az aktuális fájlpozíciótól kezdődik,

megtörténte után a fájlpozíció a fájlban következő, át nem vitt

bájtra mozdul. A fájlpozíciót fájlmutatónak is szokás nevezni.

110

Page 111: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Fájlkezelő függvények

• fseek(fp, pozíció, honnan)

Ugrás a bájtban megadott pozícióra.

A honnan értékei: SEEK_SET=elejétől, SEEK_END=végétől, SEEK_CUR=aktuális

pozíciótól számolva, a számozás itt is 0-tól kezdődik.

• ftell(fp)

Az aktuális pozíció lekérdezése (bájtokban).

• fputc(c, fp), fgetc(fp)

A putchar() és getchar() párja.

• fputs(str, fp), fgets(str, méret, fp)

A puts() és a gets() párja.

• errno

Globális változó, ami a legutolsó hiba kódját tartalmazza.

111

Page 112: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Fájlméret

• Írjunk fájlméretet

megállapító függvényt!• A fajlmeret elteszi a

pillanatnyi pozíciót az aktpoz változóba, hogy

a fájl végére állítás után

helyre tudja hozni a

fájlmutatót. A lekérdezett

fájlvég pozíció éppen a

fájlméret.

112

#include <stdio.h>

long fajlmeret(FILE *stream) {

long aktpoz, hossz;

aktpoz = ftell(stream);

fseek(stream, 0L, SEEK_END);

hossz = ftell(stream);

fseek(stream, aktpoz, SEEK_SET);

return(hossz);

}

Page 113: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Getline és scanf megfelelői fájlokra

char *fgets(char *s, int n, FILE*stream);

Vegyük észre, hogy a jegyzet eleje óta használt

getline függvény csak annyiban tér el az

fgets–től, hogy:

• A beolvasott karakterlánc méretét adja vissza.

• A szabvány bemenetről (stdin) olvas, s nem

más folyamból, így eggyel kevesebb a

paramétere.

• n karaktert hoz be legfeljebb, vagy '\n'-ig, de

magát a soremelés karaktert nem teszi be az

eredmény karakterláncba.

113

int fscanf(FILE *stream, constchar *format<, cim, ...>);

Az fscanf minden mezőt a format

karakterláncnak megfelelően konvertál, es letárol

rendre a paraméter címeken. A format

karakterláncban ugyanannyi konverziót okozó

formátumspecifikációnak kell lennie, mint ahány

bemeneti mező van

Page 114: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Fájlolvasás - szöveges fájlok

#include <stdio.h>#include <stdlib.h>

void main() {FILE *f;char c;f=fopen("C:\\temp\\szoveg.txt","rt");if(f != NULL){while((c=fgetc(f))!=EOF){

printf("%c ",c);}fclose(f);

}getchar();

}

114

#include <stdio.h>#include <stdlib.h>

void main() {FILE *f;char szoveg[100];f=fopen("C:\\temp\\szoveg.txt","rt");if(f != NULL){while((fscanf(f, "%s", szoveg))!=EOF){printf("%s\n", szoveg);

}fclose(f);

}getchar();

}

Page 115: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Fájlolvasás - szöveges fájlok

#include <stdio.h>#include <stdlib.h>#include SORHOSSZ 200

void main() {FILE *f;char sor[SORHOSSZ + 1];f=fopen("C:\\temp\\szoveg.txt","rt");if(f != NULL){while(fgets(sor,SORHOSSZ,f)){

printf("%s ",sor);}fclose(f);

}getchar();

}

115

Karakter beolvasása:c=fgetc(f);

Sor beolvasása:

fgets(sor, HOSSZ, f);

Szöveg beolvasása formázottan:

fscanf(f,"%s", szoveg);fscanf(f,"%s %s %d",s1,s2,&szam);

Page 116: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Abszolút/relatív útvonal

A fájlok elérési útvonala (path) megadható abszolút vagy relatív módon is.

Pl: C:\Solution\Debug\Project.exe

FILE *relative1;

FILE *relative2;

FILE *absolute;

relative1 = fopen("myfile.txt","r");

relative2 = fopen("data\\myfile.txt","r");

absolute = fopen("c:\\tmp\\myfile.txt","r");

116

Page 117: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - fájlolvasás

• Adott egy szöveges állomány, amelyben angol szavak

vannak, minden szó után egy szóköz áll. Írjunk programot,

amely képernyőre írja azokat a sorokat (több ilyen is lehet),

amelyekben a legkevesebb szó van!

• Feltételezhetjük, hogy a feldolgozandó állomány neve és helye c:\temp\szoveg.txt, és az állomány egyetlen sora

sem tartalmaz 200-nál több karaktert.

117Megoldás: fajlolvasas06kevesebbSzo.c

Page 118: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat – fájlolvasás CSV

• Olvasson be tetszőleges szöveges CSV állományt, ennek

elérési útvonalát parancssori paraméterekkel lehessen

megadni.

• Listázza az egyes mezőket rendre egymás utáni sorokban.

• A CSV fájlformátum szemléltetése

118Megoldás: fajlolvasas07csv.c

Page 119: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

char* kovMezo(char* sor) {

static char* mm = NULL;

char *eleje, *vege;

char idezet = 0;

if (sor) mm = sor;

else if (!mm) return NULL;

eleje = vege = mm;

while (*mm && (*mm!= ELVALASZTO || idezet)) {

if (*mm == SZOVEGHAT)

if (!idezet) idezet = 1;

else if (*(mm + 1) == SZOVEGHAT) *vege++ = *mm++;

else idezet = 0;

else *vege++ = *mm;

mm++;

}

if (*mm) mm++; else mm = NULL;

*vege = '\0';

return eleje;

}

CSV beolvasás kovMezo függvénnyel

119

SZOVEGHAT » pl.: " vagy 'ELVALASZTO » pl.: ; vagy ,

Hívása pl.:

while (fgets(sor, MAX, f)){

mezo = kovMezo(sor);

while (mezo != NULL) {

printf("\t%s", mezo);

mezo = kovMezo(NULL);

}

}

fclose(f);

Page 120: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat – fájlolvasás CSV

• Adott egy szöveges csv állomány, pontosvesszővel tagolva.

Keresse meg a Jani nevű felhasználót és írja ki a hozzá

tartozó email címet. Valósítsa meg ezt egy char*

nevKeres(char *f, char *keresendoString) prototípusú

függvénnyel.

• Feltételezhetjük, hogy a Jani létezik, további feladatként

viszont készüljön fel minél több lehetséges hibára. (hosszú

sorok, hibás fájl, nem elérhető, nem létező fájl, stb.)

120Megoldás: nevek02.c nevek01.c

Page 121: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - szöveges fájl1 írás

#include <stdio.h>#include <stdlib.h>

void main(){FILE *f = fopen("c:\\temp\\szoveg.txt", "w"); if (f == NULL){

printf("Hiba\n");getchar();

}else {

fprintf(f, "Szoveg.\nEs meg tobb szoveg.");fclose(f);

}}

121

Page 122: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

CSV fájlformátum

Notepad

szinusz1;szinusz2;koszinusz10,0500;0,1100;0,99880,0998;0,2598;0,99500,1494;0,2494;0,98880,1987;0,2587;0,98010,2474;0,3074;0,96890,2955;0,3155;0,95530,3429;0,4429;0,93940,3894;0,5000;0,92110,4350;0,5350;0,90040,4794;0,5194;0,87760,5227;0,5827;0,8525

Excel

szinusz1 szinusz2 koszinusz1

0,05 0,11 0,9988

0,0998 0,2598 0,995

0,1494 0,2494 0,9888

0,1987 0,2587 0,9801

0,2474 0,3074 0,9689

0,2955 0,3155 0,9553

0,3429 0,4429 0,9394

0,3894 0,5 0,9211

0,435 0,535 0,9004

0,4794 0,5194 0,8776

0,5227 0,5827 0,8525

122Coma Separated Values, szöveg alapú fájl

Page 123: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - szöveges fájl2

Írjon CSV fájlba szinusz, véletlenszámmal módosított szinusz és koszinusz értékeket.

Figyeljen a helyi beállítások használatára (tizedes vessző!)

123Megoldás: fajliras02csv.c

szinusz1 szinusz2 koszinusz1

0,05 0,11 0,9988

0,0998 0,2598 0,995

0,1494 0,2494 0,9888

0,1987 0,2587 0,9801

0,2474 0,3074 0,9689

0,2955 0,3155 0,9553

0,3429 0,4429 0,9394

0,3894 0,5 0,9211

0,435 0,535 0,9004

0,4794 0,5194 0,8776

0,5227 0,5827 0,8525

-1.5

-1

-0.5

0

0.5

1

1.5

1 9 17 25 33 41 49 57 65 73 81 89 97 105113 121129137145153161169177185193

szinusz1 szinusz2 koszinusz1

Page 124: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat – szöveges fájl3

• Hozzon létre a felhasználó által megadatott

nevű fájlt, majd írjon bele egy sakktábla

mintázatot a felhasználó által megadott

mérettel.

124

* * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * * * * * * * * * * *

Megoldás: fajliras03csillag.c

Page 125: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - szövegfájl egyesítés

Készítsen programot, mely az indító parancssorban megadott szövegfájlokat egyesíti a megadás sorrendjében a parancssorban utolsóként előírt azonosítójú szövegfájlba! Ha parancssori paraméter nélkül indítják a programot, akkor ismertesse a képernyőn, hogyan kell használni! Ha csak egy fájlazonosító van a parancssorban, akkor a szabvány bemenet másolandó bele. A fájlok egyesítése során a folyamat előrehaladásáról tájékoztatni kell a képernyőn! A szabvány bemenet másolása esetén végül közlendő az eredményfájl mérete!

125

Page 126: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - szövegfájl

Készítsen programot, mely eldönti az indító parancssorban

megadott azonosítójú fájlról, hogy ASCII kódú szövegfájl-e,

vagy bináris fájl-e! Ha parancssori paraméter nélkül futtatják a

programot, akkor ismertesse a képernyőn a használatát!

126

Page 127: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat – szöveges fájl 8

• Írjunk programot, amely egy létező szöveges állomány

minden sorát 80 karakter hosszúságúra egészíti ki

szóközökkel, ha a sorok 80 karakternél rövidebbek, és

csonkítja őket a végükön, ha 80 karakternél hosszabbak! Az

új sorokat egy új szöveges állományba kell írni.

127Megoldás: fajlolvasas08.c

Page 128: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Könyvtárak listázása

#include <stdio.h>#include <io.h>#include <direct.h>#include <conio.h>#include <ctype.h>#include <string.h>

void main(){char path[50] = "C:\\temp";struct _finddata_t fajlLista;long hFile;if(mkdir("C:\\temp\\ujMappa"))fprintf(stderr, "Nem hozhato letre a mappa\n");

printf("Listazzuk a %s tartalamt\n\n", path);if(_chdir(path))fprintf(stderr, "Nem talalom: %s\n", path);

else{hFile = _findfirst("*.*", &fajlLista);while(_findnext(hFile, &fajlLista) == 0){if(!strcmp(fajlLista.name, "Program Files") || !strcmp(fajlLista.name, "ujMappa"))

printf("- %s\n", fajlLista.name);else

printf(" %s\n", fajlLista.name);}_findclose(hFile);

}getchar();

}

128

Page 129: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Időkezelés

• ANSI/ISO szabványos függvények lekérdezik, tárolják, konvertálják, stb. az aktuális

(rendszer) időt. Két típusuk:» Az időzónának megfelelő helyi idő.

» Egyezményes (UTC) naptári idő, amit korábban greenwichi közép időnek (GMT) neveztek.

• Kezelése: time.h fejfájl. Típusok és típusok közti konverziók.

129

típusok

függvények

Jelmagyarázat:

struct tm*

char *

double

time_ttime ctime

1970 óta eltelt

másodpercek

Idők különbségei

másodpercben

Dátum, idő

struktúraként

Dátum, idő stringként

Page 130: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Időkezelés

Több függvény osztozik két statikus élettartamú pufferen. Ezek:

• Az idő karakterlánc char * típusú, statikus karaktertömbben. Pontosan 26

karakteres: "Tue Jan 05 12:03:55 1999\n\0" formájú. 24-órás az

időszámítás. Minden mező konstans szélességű. Az új sor és a lezáró null

karakter mindig a vég.

• Az idő struktúra struct tm típusú struktúra, melynek tagjai int–ek. A

tagok:

» tm_sec: Másodperc (0–59).

» tm_min: Perc (0–59).

» tm_hour: Óra (0–23).

» tm_mday: Nap a hónapon belül (1–31).

130

Page 131: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Időkezelés

• Az idő struktúra tagjai még:

» tm_mon: Hónap az éven belül (0–11, a január a 0).

» tm_year: Év - 1900.

» tm_wday: A hét napja (0–6, a vasárnap a 0).

» tm_yday: Napszám az éven belül (0–365, a január 1 a zérus).

» tm_isdst: Nyári időszámítás jelző, mely pozitív, ha a nyári

időszámítás hatályban van, és 0, ha nincs. Negatív a jelző, ha a

nyári időszámítás állapota ismeretlen.

131

Page 132: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• A time_t aritmetikai típus (többnyire long).

• A time_t time(time_t *sectime); függvény az aktuális

rendszer időt 1970. január elseje éjfél óta eltelt másodpercek

számában, time_t típusban szolgáltatja.

• A double difftime(time_t ido1, time_t ido0);

visszaadja az ido1 és az ido0 naptári idők különbségét,

azaz a közben eltelt időt másodpercekben.

Időkezelés

132

Page 133: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

size_t strftime (char *puffer, size_t maxmeret, const char *format,

const struct tm *idoptr);

size_t wcsftime (wchar_t *puffer, size_t maxmeret, const wchar_t

*format, const struct tm *idoptr);

• Az strftime és a wcsftime függvények az idoptrmutatta, struct tm típusú időértéket megformázzák a

format vezérlő karakterláncban előírtak szerint, és az

eredmény karakterláncot elhelyezik a legfeljebb maxmeretkarakteres puffer–ben. A függvények között, hogy a

különbség a puffer 1 vagy 2 bájtos karakter-e.

Időkezelés

133

Page 134: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

struct tm *gmtime (const time_t *ido);

struct tm *localtime (const time_t *ido);

• A függvények a paraméter, time_t típusú, GMT (UTC, vagy

egyezményes) idő értéket statikus, tm típusú struktúrába

konvertálják, és ennek az idő struktúrának a címét visszatérési

értékként szolgáltatják. Ha az ido érték 1970. január elseje

éjfél előtti, akkor a rutinok NULL mutatót adnak vissza. A

localtime korrigálja az időt a helyi időzónára, míg a

gmtime ilyet nem tesz.

Időkezelés

134

Page 135: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

char *ctime (const time_t *ido);

• Az ido mutatta, time_t típusú időt alakítja a helyi időzóna

beállításoknak is megfelelő idő karakterlánccá. A fenti

függvény elhelyezi a statikus pufferben, és erre mutató

mutatót ad vissza.

Időkezelés

135

Page 136: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Időkezelés

#include <stdio.h>#include <time.h>void main(){

int yy, mm, dd;struct tm when = {0};char buffer[100] = "";// dátum beolvasásasscanf_s("2015.12.31", "%d.%d.%d",

&yy, &mm, &dd);when.tm_year = yy - 1900;when.tm_mon = mm - 1;when.tm_mday = dd;mktime(&when);

// kiíratás v1strftime(buffer,80,"%Y %b %d %I:%M%p --

%c\n", &when);printf(buffer);

136

// kiíratás v2

printf("%d.%d.%d (%d. nap)\n",

1900 + when.tm_year, when.tm_mon +

1, when.tm_mday, when.tm_yday + 1);

// nap növelése

when.tm_mday+=1;

mktime(&when);

//kiíratás újra

printf("%d.%d.%d (%d. nap)\n",

1900 + when.tm_year, when.tm_mon +

1, when.tm_mday, when.tm_yday + 1);

getchar();

}

2015 Dec 31 12:00AM -- 12/31/14 00:00:002015.12.31 (365. nap)2016.1.1 (1. nap)

Page 137: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Várakozás [ms]

• #include <Windows.h> //így OS függő leszSleep(900); //900 ms = 0,9 másodperc

• #include <stdlib.h> _sleep(900); //obsolete – elavult

• Más nyelveken általában delay, wait vagy sleep esetleg

pause.

137

Page 138: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Várakozás [sec]

#include <time.h>

void sleep(clock_t sec) {

clock_t ig = sec*CLOCKS_PER_SEC + clock();

while (ig > clock());

}

• A clock_t clock(); függvény a hívó folyamat által elhasznált

processzor időt szolgáltatja, a clock_t aritmetikai típus (többnyire long).

• A clock által visszaadott értékből úgy kapunk másodpercet, hogy elosztjuk

a CLOCKS_PER_SEC szimbolikus állandóval.

• Tehát a fenti függvény sec másodpercet vár.

138

Page 139: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;

• Nézzük az idok.c példaprogramot, amely illusztrálja jó

néhány időkezelő függvény használatát.

Feladat

139Megoldás: idok.c

1970. januar 1. ota eltelt masodpercek szama: 1460891778A UNIX ido es datum: Sun Apr 17 13:16:18 2016Az egyezmenyes ido: Sun Apr 17 11:16:18 201612-oras ido: 01:16:18 duKaracsony Fri Dec 25 12:00:00 2020Karacsony + 10 nap: Mon Jan 4 12:00:00 20212021. January 4. Monday van a(z) Romance Standard Time idozonaban.2021. január 4. hétfo van a(z) Romance Standard Time idozonaban.

Page 140: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Változó paraméterlista

• Néhány fv. hívásonként eltérő számú paramétert fogad, pl.:

int printf(const char *format, ...);

• stdarg.h

typedef char *va_list;#define _INTSIZEOF(x) ((sizeof(x)+sizeof(int)-1)&~(sizeof(int) -1))#define va_start(ap, utsofix) (ap=(va_list)&utsofix+_INTSIZEOF(utsofix))#define va_arg(ap, tipus) (*(tipus *)((ap+=_INTSIZEOF(tipus)) - _INTSIZEOF(tipus)))#define va_end(ap) ap = (va_list)0

Page 141: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Változó paraméterlista

#include <stdio.h>#include <stdarg.h>void sum(char *uzen, ...) {

int osszeg = 0, tag;va_list param;va_start(param, uzen);while(tag = va_arg(param, int)) osszeg += tag;va_end(param);printf(uzen, osszeg);

}void main() {

sum("1+2+3+4 = %d\n", 1, 2, 3, 4, 0); getchar();

}

Page 142: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat – változó paraméterlista 1

• Írjunk egy változó paraméterszámú függvényt, amely

összefűz tetszőleges számú sztringet, és az így kapott új

sztringgel tér vissza! A függvény első paramétere az

összefűzendő sztringek darabszáma, további paraméterei

pedig maguk a sztringek.

• konkat(5, "Ez ", "egy ", "jó ", "hosszú ", "sztring!");

142Megoldás: valtozoparam01.c

Page 143: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat – változó paraméterlista 2

• Írjunk egy változó paraméterszámú függvényt, amely

összefűz tetszőleges számú sztringet, és az így kapott új

sztringgel tér vissza! A függvény legalább egy sztringet vár paraméterként, utolsó paraméterének a NULL pointernek kell

lennie, ezzel jelezzük a paraméterlista végét.

• konkat("Ez ", "egy ", "jó ", "hosszú ", "sztring", NULL);

143Megoldás: valtozoparam02.c

Page 144: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Numerikus integrálás húrtrapézformulával

• A trapéz szabály egy közelítő numerikus eljárás a határozott

integrál meghatározására

144

න𝑎

𝑏

𝑓 𝑥 𝑑𝑥 ≈ (𝑏 − 𝑎)𝑓 𝑏 + 𝑓(𝑎)

2

Page 145: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Numerikus integrálás húrtrapézformulával

145

න𝑖

𝑖+1

𝑓 𝑥 𝑑𝑥 ≈ ∆𝑇𝑥[𝑖] + 𝑥[𝑖 + 1]

2

dT * (x[i] + x[i+1]) / 2.0

Page 146: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Numerikus integrálás húrtrapézformulával

146

න𝑖

𝑖+1

𝑓 𝑥 𝑑𝑥 ≈ ∆𝑇𝑥[𝑖] + 𝑥[𝑖 + 1]

2

// x - az integrálandó tömb// xSize - x mérete// dT - delta T a mintavételezés időközedouble numIntegralTrapez(double *x, int xSize, double dT){

int i;double result = 0;for(i = 0; i < xSize - 1; i++)

result += (dT * (x[i] + x[i+1]) / 2.0);return result;

}

Page 147: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - Szenergy

• A csatolt szenergy_2014_10_18_17_18_murcia.csv és

szenergy_2014_10_17_16_06_rotterdam.csv táblázatos formában

tartalmazza egyetemünk Szenergy hallgatói csapatának telemetriás

adatait egy spanyol és egy holland versenyről.

• Feladatunk a rendelkezésekre álló adatokból a körönként megtett

távolság kiszámítása. Mivel a fájl tartalmazza a körök számát is az

értékekhez, így nem csak a verseny, de a körönkénti távolság is

kiszámítható. Ezek közel azonos érték kellenek, hogy legyenek, de

előzések és a pályán belüli eltérő nyomvonalak okozhatnak némi eltérést.

• Figyeljünk rá, hogy csak m/s-ből tudunk métert számolni.for (i = 0; i < recordNumber; i++) pSpeedMps[i] = pSpeedKmph[i] / 3.6;

147Megoldás: szenergy00.c szenergy01.c szenergy02.c

Page 148: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Lineáris és Lagrange interpoláció

148

0

5

10

15

20

25

30

35

1 1.2 1.4 1.6 1.8 2 2.2 2.4 2.6 2.8 3 3.2 3.4 3.6 3.8 4 4.2 4.4 4.6 4.8 5

Lineáris

interpolált alappontok

0

5

10

15

20

25

30

1 1.2 1.4 1.6 1.8 2 2.2 2.4 2.6 2.8 3 3.2 3.4 3.6 3.8 4 4.2 4.4 4.6 4.8 5

Lagrange

interpolált alappontok

Page 149: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - interpoláció

• Vegyük a példaként is említett alappont-érték párosokat.

• Írjunk programot, amely a standard kimenetre kiírja 0,1-es lépésközzel az interpoláció értékeit mind Lagrange, mind lineáris módszerrel. Plusz feladatként írjuk csv fájlba az eredményt.

Megoldás: interpolacio01.c

149

𝑥0 = 1; 𝑦0 = 10,3𝑥1 = 2; 𝑦1 = 18,956𝑥2 = 3,3; 𝑦2 = 12𝑥3 = 5; 𝑦3 = 30

Page 150: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Lineáris és Lagrange interpoláció

150

// *x - az interpolációs alappontok helye// *y - az interpolációs alappontok értéke// n - az interpolációs alappontok darabszáma (*y és *y tömb

elemszáma)// x1 - a hely, ahol meg szeretnek kapni *y1 érteketint linInterp(double *x, double *y, int n, double x1, double *y1){int i;for (i = 0; i < n - 1; i++){

if ((x[i] <= x1) && (x[i + 1] >= x1)){*y1 = y[i] + (y[i + 1] - y[i]) / (x[i + 1] - x[i])*(x1 - x[i]);return 0;

}}return 1;

}

int lagrangeInterp(double *x, double *y, int n, double x1, double *y1){double p = 0.0, s;int i, j;for (i = 0; i < n; i++){s = 1.0;for (j = 0; j < n; j++){

if (i != j){if (x[i] == x[j]) return 1;else s = s*(x1 - x[j]) / (x[i] - x[j]);

}}p += y[i] * s;

}*y1 = p;return 0;

}

Page 151: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Header fájlok

• Kódfájlok (.c) függvények definíciói

• Fejlécfájlok (.h) mennek a függvények deklarációi#include <stdio.h>#include "sajat.h"» A két megadás között a különbség annyi, hogy más mappában

keresi majd a fordító.

151

Page 152: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Header fájlok

Az alábbi példában is a kódfájlokban (.c) a függvények definíciói, a fejlécfájlokban

pedig (.h) a függvények deklarációi kaptak helyet.

152

#include <stdio.h>

#include "oraifuggvenyek.h"

void main(){

char s[21];

getline(s, 20);

printf(s);

}

#include <stdio.h>

#include "oraifuggvenyek.h"

int getline(char *s, int n){

int c;

char *t = s;

while (n-- > 0 && (c =

getchar()) != EOF&&c !=

'\n') *t++ = c;

*t = '\0';

while (c != EOF&&c != '\n')

c = getchar();

return(t - s);

}

int getline(char *s, int n);

main.c oraifuggvenyek.h oraifuggvenyek.c

opcionális

Page 153: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - autószerviz

• Egy autószerviz számítógépe minden megbízásról egy-egy sort ír a

SZERVIZ.TXT fájlba. Egy sor a következő adatokat tartalmazza pontosvesszővel

elválasztva:

RENDSZÁM : 6 karakterTULAJDONOS NEVE : 40 karakter (legfeljebb 40)FORG. ENG. SZÁMA : 8 karakterDÁTUM : 11 karakter (2013.02.19.)ÖSSZEG : 6 karakter (legfeljebb 6 karakter, egész szám)

• Írjon C programot, amely a SZERVIZ.TXT fájl alapján névsorban kiírja azoknak

az autótulajdonosoknak a nevét, akik az átlagosnál többször javíttatták 2013

februárjában autójukat. A fájlt csak egyszer olvashatja be!

• Használjon dinamikus adat szerkezetet!

153Megoldás: szerviz.c

Page 154: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Feladat - email címek

• Írjon egy olyan szabványos ANSI C programot, amely parancssori paraméterként kapja két

szövegfájl nevet! Az első fájl egy weboldalt leíró html szöveg.

• A program gyűjtse ki a fájlban található e-mail címeket, melyeket aztán lista adatszerkezetben

taroljon (egy címet elég egyszer eltarolni)! Az e-mail címek olyan karaktersorozatok, melyek az

angol ABC kis- es nagybetűiből, számokból, pontokból (.), kötőjelekből(-) es aláhúzás (_) jelekből

állnak, es kötelezően tartalmaznak pontosan egy @ karaktert. Az email címben nem állhat

egymás mellett két pont, valamint nem állhat egymás mellett egy pont es egy @. Minden egyéb,

itt fel nem sorolt karakter elválasztó karakternek minősül. Egy e-mail cím hossza maximum 100

karakter. Ha ennél hosszabb, amúgy érvényes karaktersorozatra bukkanunk, azt ne tekintsük e-

mail címnek! A nem e-mail cím karaktersorozatok hossza bármekkora lehet, ezek fix hosszúságú

tömbben való eltarolása súlyos hibának minősül.

• A második parancssori paraméterként kapott szövegfájl minden sora egy-egy, korábban kigyűjtött

e-mail címet tartalmaz. A program olvassa be az e-mail címeket, es fésülje össze a most talált

címekkel, majd mentse el ugyanebbe a fájlba az összes címet abc sorrendben, minden címet csak

egyszer taroljon!

154

Page 155: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;_CRT_SECURE_NO_WARNINGS

Project » Properties » Configuration

properties » C/C++ » Prepocessor

_CRT_SECURE_NO_WARNINGS

_CRT_NONSTDC_NO_WARNINGS

Amennyiben a következő error fogad,

akkor célszeű használni: "This function or

variable may be unsafe."

155

Page 156: *p2; - Széchenyi István Egyetemherno/NGB_IN001_2/prog2.pdf · 17 •Olvasson be a szabvány bemenetről egy karakterláncot! Egy alkalmas függvény segítségével alakítsa át

*p2;Felhasznált irodalom

• A C programozási nyelv - Az ANSI szerinti változat. B.

W. Kernighan - D. M. Ritchie; Műszaki Könyvkiadó, 1995

• Programozás C nyelven - Pere László, Kiskapu 2003

• Programozási feladatok és algoritmusok Turbo C és C++

nyelven Benkő Tiborné, Benkő László, ComputerBooks 1997

• A programozás alapjai - Pohl László, Budapest, 2010

• Programozás I-II. C programnyelv - Bauer Péter, Universitas-

Győr Kht., 2005

156