75
Procedurálne programovanie: 6. prednáška Gabriela Kosková

Procedur álne programovanie: 6 . prednáška

Embed Size (px)

DESCRIPTION

Procedur álne programovanie: 6 . prednáška. Gabriela Kosková. Obsah. príklady (defin ície + 1 príklad) jednorozmern é polia príklady (3) re ťazce. Procedur álne programovanie: Pr ác a s ukazovateľmi - príklad y. Pr íklady definícií. typu int. - x je. int x;. typ int. - PowerPoint PPT Presentation

Citation preview

Page 1: Procedur álne programovanie: 6 . prednáška

Procedurálne programovanie:6. prednáška

Gabriela Kosková

Page 2: Procedur álne programovanie: 6 . prednáška

Obsah

1. príklady (definície + 1 príklad)

2. jednorozmerné polia

3. príklady (3)

4. reťazce

Page 3: Procedur álne programovanie: 6 . prednáška

Procedurálne programovanie:Práca s ukazovateľmi - príklady

Page 4: Procedur álne programovanie: 6 . prednáška

Príklady definícií

int x; - x je

int *y; - y je

int *z(); - z je

int (*v)(); - v je

int *(*w)(); - w je

typu int

ukazovateľ na typ int

funkcia vracajúca ukazovateľ na int

ukazovateľ na funkciu vracajúcu int

ukazovateľ na funkciu vracajúcu

ukazovateľ na int

Page 5: Procedur álne programovanie: 6 . prednáška

Príklad

program načíta celé číslo n a alokuje blok pamäte pre n celých

čísel. Od používateľa čísla načíta. Nakoniec vypočíta ich

priemer.

Page 6: Procedur álne programovanie: 6 . prednáška

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

int *alokuj(int pocet);void nacitaj(int *pole, int pocet);float priemer(int *pole, int pocet);void vypis(int *pole, int pocet);

int main(){ int *pole, n;

printf("Zadajte pocet cisel: "); scanf("%d", &n); if ((pole = alokuj(n)) == NULL) { printf("Nepodarilo sa alokovat pole.\n"); return 1; } nacitaj(pole, n); printf("Priemer cisel: \n"); vypis(pole, n); printf("je %.3f.\n", priemer(pole, n)); free(pole); return 0;}

Page 7: Procedur álne programovanie: 6 . prednáška

int *alokuj(int pocet){ return (int *) malloc(pocet * sizeof(int));}

void nacitaj(int *pole, int pocet){ int i; for(i = 0; i < pocet; i++) { printf("%d-te cislo: ", i); scanf("%d", pole + i); }}

float priemer(int *pole, int pocet){ int i, suma = 0; for(i = 0; i < pocet; i++) suma += *(pole + i); return (float) suma / (float) pocet;}

Page 8: Procedur álne programovanie: 6 . prednáška

void vypis(int *pole, int pocet){ int i; for(i = 0; i < pocet; i++) printf("%d, ", *(pole + i));}

Page 9: Procedur álne programovanie: 6 . prednáška

Procedurálne programovanie: Jednorozmerné polia

Page 10: Procedur álne programovanie: 6 . prednáška

Základy práce s poliami

• pole je štruktúra zložená z niekoľkých prvkov rovnakého typu (blok prvkov)

TYP x[N];

– pole obsahuje N prvkov– dolná hranica je vždy 0

horná hranica je N-1– číslo N musí byť známe v čase prekladu – hodnoty nie sú inicializované na 0

statická definícia poľa

5

6

7

N: 3TYP: int

index:

0

1

2

Page 11: Procedur álne programovanie: 6 . prednáška

Príklady definícií statického poľa

#define N 10

int x[N], y[N+1], z[N*2];

x má prvkov poľa, od indexu po index y má prvkov poľa, od indexu po index z má prvkov poľa, od indexu po index

10 0 9

11 0 10

20 0 19

Page 12: Procedur álne programovanie: 6 . prednáška

Prístup k prvkom poľa

#define N 10

... int x[N], i;

x[0] = 1;

priradenie hodnoty do prvého prvku poľa

for (i = 0; i < N; i++) x[i] = i+1;

v cykle priradenie hodnoty postupne

všetkým prvkom poľa

for (i = 0; i < N; i++) pritnf("x[%d]: %d\n", i, x[i]);

výpis prvkov poľa

Page 13: Procedur álne programovanie: 6 . prednáška

Príklad statického poľa: histogram písmen v reťazci#include <stdio.h>#include <stdlib.h>#define N ('Z' - 'A' + 1)

int main() { int i; char hist[N], slovo[100];

scanf("%s", slovo); /* nacitanie slova */ for (i = 0; i < N; i++) /* inicializacia hist */ hist[i] = 0;

i = 0; /* naplnenie hist */ while (i < 100 && slovo[i] != '\0') { hist[toupper(slovo[i]) - 'A']++; i++; }

pokračovanie

Page 14: Procedur álne programovanie: 6 . prednáška

Príklad statického poľa: histogram písmen v reťazci

for(i = 0; i < N; i++) /* vypis hist */ if(hist[i] != 0) printf("%c: %d\n", i+'A', hist[i]);

return 0;}

pokračovanie:

Page 15: Procedur álne programovanie: 6 . prednáška

Inicializácia poľa v definícii

...int x[3] = { 1, 2, 3 };int y[] = { 1, 2, 3 };int z[5] = { 1, 2, 3 };...

int n = 5;int z[n];

Počet prvkov poľa je daný počtom hodnôt

Hodnoty z[3] a z[4] sú inicializované na 0.

Nie je povolené, keďže n je premenná a nie číslo alebo konštanta (t.j.

hodnota nemusí byť známa v čase prekladu)

Page 16: Procedur álne programovanie: 6 . prednáška

Polia a ukazovatele

• adresa i-teho prvku poľa x:

&x[i] = bázová adresa x + i * sizeof(typ)– x je adresa v pamäti

• platí: x + i == &x[i]

*(x + i) == x[i]

Page 17: Procedur álne programovanie: 6 . prednáška

Polia a ukazovatele

• platí:– p[0] == *p– p[1] == *(p + 1)– p[2] == *(p + 2)– p[3] == *(p + 3)

int *p;p = (int *) malloc(4 * sizeof(int));

Rozdiel medzi statickými a dynamickými poliami je najmä v spôsobe prideľovania pamäte.

Page 18: Procedur álne programovanie: 6 . prednáška

Polia a ukazovatele

• platí:– &x[0] == &*(x + 0) == x– &x[i] == &*(x + i) == (x + i)

int x[4];

x je statický ukazovateľ, nemôžeme spraviť x = p_i;

môžeme ale urobiť *x = 2; (to isté ako x[0] = 2;)

Page 19: Procedur álne programovanie: 6 . prednáška

Príklad prístupu k prvkom poľa pomocou ukazovateľa

i = 0; /* naplnenie pola */while (i < N && (slovo[i] != '\0') { hist[toupper(slovo[i]) - 'A']++; i++;}

Prepísanie nasledujúcej časti programu tak, aby sa k poľu slovo pristupovalo prostredníctvom ukazovateľov.

i = 0; /* naplnenie pola */while (i < N && (*(slovo + i) != '\0') { hist[toupper(*(slovo + i)) - 'A']++; i++;}

Page 20: Procedur álne programovanie: 6 . prednáška

Zistenie veľkosti poľa

• po alokovaní pamäte pre p_x budú x aj p_x ukazovatele na pole 10 prvkov typu int, s rozdielom, že:– x je statický ukazovateľ– p_x je dynamický ukazovateľ

• preto dáva sizeof() iné výsledky:

sizeof(x) == 10 * sizeof(int) (napr. 20)

sizeof(p_x) == sizeof(int *) (napr. 4)

int x[10], *p_x;p_x = (int *) malloc (10 * sizeof(int));

Page 21: Procedur álne programovanie: 6 . prednáška

Pole meniace svoju veľkosť

int *x, n = 5, *p1, *p2, *p;

x = (int *) malloc(n * sizeof(int)); x[0] = 10; x[4] = 3; ... /* potreba zvacsit pole*/p = (int *) malloc (10 * n * sizof(int)); p1 = x; p2 = p; while(p1 < x + n) *p2++ = *p1++;n *= 10;free(x); x = p;

alokovaniepoľa x

alokovaniepoľa p

kopírovanie obsahu poľa

uvoľnenie menšieho poľa x

nastavenie x na p

Page 22: Procedur álne programovanie: 6 . prednáška

Pole meniace svoju veľkosť - pomocou realloc()

• funkcia

void *realloc(void *pole, unsigned int size) definovaná v stdlib.h– pole - ukazovateľ na pamäť– size - veľkosť– zväčší pole, alebo vytvorí nové a prekopíruje tam

hodnoty z pôvodného poľa

x = realloc(x, 10 * n * sizeof(int));

Page 23: Procedur álne programovanie: 6 . prednáška

Pole ako parameter funkcie

• identifikátor nasledovaný zátvorkami:

int pole[]

int maximum(int pole[], int n) { int *p_max = pole, *p; for (p = pole + 1; p < pole + n; p++) { if (*p > *p_max) p_max = p; } return (*p_max);} nepozná veľkosť poľa,

preto ju treba uviesť

vráti maximum z prvkov poľa

pole

Page 24: Procedur álne programovanie: 6 . prednáška

• vo funkcii sa nedá zistiť veľkosť poľa

aj keď:

Pole ako parameter funkcie: veľkosť poľa

int maximum(int pole[], int n)

int maximum(int pole[10])

• parameter bude stále považovaný za pole[]

parameter sa dá vo funkcii meniť (lebo sa vytvorila jeho lokálna kópia (nezáleží na tom, či ide o statické alebo dynamické pole)

Page 25: Procedur álne programovanie: 6 . prednáška

Pole ako parameter funkcie

int pole[] je ekvivalentné int *pole

max = maximum(pole, 10);

Volanie funkcie s poľom ako parametrom:

Pri použití int pole[] je jasnejšie, že ide o pole a nie o ukazovateľ na int.

Page 26: Procedur álne programovanie: 6 . prednáška

Pole ako parameter funkcie

int maximum(int pole[], int n) {...}int maximum(int *pole, int n) {...}

int x[10];max = maximum(x + 2, 5);int x[10];max = maximum(&x[2], 5);

• dá sa použiť aj na zistenie maxima napr. na zistenie maxima 3. až 7. prvku

Page 27: Procedur álne programovanie: 6 . prednáška

void maximum(int pole[], int n, int *p_max) { int *p; *p_max = pole[0]; for (p = pole + 1; p < pole + n; p++) { if (*p > *p_max) *p_max = *p; }}

Pole ako parameter funkcie

• prepísanie funkcie maximum() na procedúru

ak by sme dali p_max = p; stratili by sme ukazovateľ na premennú, kam treba vrátiť maximum

Page 28: Procedur álne programovanie: 6 . prednáška

void init(double **p_f) { double a[5]; int i;

for(i = 0; i < 5; i++) { printf("Zadaj %d. cislo"); scanf("%lf", &a[i]); } *p_f = a;}

Pole ako parameter funkcie: vytváranie poľa vo funkcii

void main() { double *p_d; init(&p_d);}

double *a;int i;a = (double *) malloc(5 * sizeof(double);

p_d bude ukazovať na pole 5 double prvkov, ale a bolo vyrobené v zásobníku, a tento zásobník sa pri ukončovaní funkcie zruší

Page 29: Procedur álne programovanie: 6 . prednáška

Pole ukazovateľov na funkcie

• prvkami poľa môžu byť aj ukazovatele– na prvky viacrozmerné polia– na funkcie (všetky funkcie musia byť toho istého typu)

typedef void (* P_FNC)();

P_FNC funkcie[10];

definícia ukazovateľa na funkciu vracajúcu typ void

pole 10 ukazovateľov

Page 30: Procedur álne programovanie: 6 . prednáška

Pole ukazovateľov na funkcie

typedef void (* P_FNC)();

P_FNC funkcie[5] = {file, edit, search, compile, run} ;...

• pole ukazovateľov na funkcie pri riadení programu pomocou menu

• volanie funkcie:

funkcia[1]();

Page 31: Procedur álne programovanie: 6 . prednáška

Ako čítať zložitejšie definície 2

• do čítania definícií treba začleniť polia

• definície sa čítajú rovnako, len treba brať do úvahy aj []

Page 32: Procedur álne programovanie: 6 . prednáška

Príkady zložitejších definícií

double (*f[])(); - f je pole ukazovateľov na funkcie vracajúce typ double

double (*f())[]; - f je funkcia vracajúca ukazovateľ na pole prvkov typu double

double *(f[])(); - f je pole funkcií vracajúce ukazovateľ na typ double

double *f()[]; - f je funkcia vracajúca pole ukazovateľov na typu double

Page 33: Procedur álne programovanie: 6 . prednáška

Ako čítať zložitejšie definície 2

double (* f())[];

• Nájdeme identifikátor

f- f je

a hľadáme ) doprava

f()

• Nájdeme ()

funkcia vracajúca

a pokračujeme doprava

f())

• Nájdeme ) a k nej zodpovedajúcu (

(* f())ukazovateľ na

a pokračujeme doprava• Nájdeme []

pole prvkov typu

(* f())[]

, pokračujeme doprava po ;

(* f())[];

• Nájdeme double

double

double (* f())[];

, doľava

Page 34: Procedur álne programovanie: 6 . prednáška

Procedurálne programovanie:Príklady

Page 35: Procedur álne programovanie: 6 . prednáška

Príklad 1

Program vytvorí histogram výskytov písmen v súbore (pre každé písmeno -

počet jeho výskytov)

Page 36: Procedur álne programovanie: 6 . prednáška

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

#define SUBOR "pismena.txt"#define N 'Z' - 'A' + 1

int main(){ int c, i, hist[N]; FILE *fr;

if((fr = fopen(SUBOR, "r")) == NULL) { printf("Subor sa nepodarilo otvorit.\n"); return 1; }

for (i=0; i<N; i++) hist[i] = 0;

while ((c = toupper(getc(fr))) != EOF) { if(c >= 'A' && c <= 'Z') hist[c - 'A']++; } pokračovanie

Page 37: Procedur álne programovanie: 6 . prednáška

for (i=0; i<N; i++) if (hist[i] != 0) printf("%c: %2d\n", 'A' + i, hist[i]);

if(fclose(fr) == EOF) { printf("Subor sa nepodarilo zatvorit.\n"); return 1; }

return 0;}

pokračovanie:

Príklad 1

Page 38: Procedur álne programovanie: 6 . prednáška

Príklad 2: Eratostenovo sito

• algoritmus na nájdenie prvočísel v poli – vyškrtáva všetky násobky prvočísel, počnúc 2

(vyškrtnutie prepísanie čísla na 0)

v cykle, i od 0 do 2 poľa prv: v cykle, k od i+1 do 14: vyškrtneme všetky násobky čísla prv[i]

i:prv[i]:

0

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14

0 0

2

0 0 0 0 0 0

13

0

20

Page 39: Procedur álne programovanie: 6 . prednáška

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

void main() { int n, i, k, odm; int *prv;

printf("Do ktoreho cisla hladat prvocisla? "); scanf("%d", &n);

n--; /* znizime n o 1, nevyskrtavame nasobky jednotky */ prv = (int *) malloc(n * sizeof(int)); for(i = 0; i < n; i++) /* inicializacia */ prv[i] = i+2;

Príklad 2: Eratostenovo sito

pokračovanie

Page 40: Procedur álne programovanie: 6 . prednáška

odm = (int) sqrt(n)-1; printf("odmocnina: %d\n", o);

for(i = 0; i < odm; i++) { if(prv[i] != 0) { /* ak sme predtym cislo nevyskrtli */ for(k = i+1; k < n; k++) { /* vyskrtni vsetky nasobky */ if(prv[k] != 0) { /* ak este nie je vyskrtnute */ if(prv[k] % prv[i] == 0) /* ak je delitelne */ prv[k] = 0; } } } }

printf("Prvocisla: "); /* vypisanie prvocisel */ for(i = 0; i < n; i++) if(prv[i] != 0) printf("%d, ", prv[i]);

putchar('\n'); return 0;}

pokračovanie:

Page 41: Procedur álne programovanie: 6 . prednáška

Príklad 3

...for (p = p1; p < p1 + N; *p2++ = *p++) ;

program na rýchle kopírovanie bloku pamäte z miesta, kam ukazuje p1 na miesto, kam ukazuje p2. Treba

použiť pomocný ukazovasteľ p

Page 42: Procedur álne programovanie: 6 . prednáška

Procedurálne programovanie:Reťazce

Page 43: Procedur álne programovanie: 6 . prednáška

Čo sú to reťazce

• reťazce sú jednorozmerné polia typu char– dĺžka reťazca: ľubovoľná, obmedzená veľkosťou

pamäte– z celkovej pamäte je aktívna len časť od začiatku poľa

do znaku '\0' ukončovací znak– ak nie je reťazec ukončený znakom '\0', považuje sa

za reťazec celá pamäť až do najbližšieho znaku '\0'

Page 44: Procedur álne programovanie: 6 . prednáška

Definícia a inicializácia reťazca

a

h

o

j

\0

• reťazec s najviac 6 znakmi:– staticky:

– dynamicky:

s: 0

1

2

3

4

5

char s[6];

char *s;s = (char *) malloc(6);

char s[] = "abrakadabra";

= "ahoj";

inicializuje sa miesta práve pre daný text

Page 45: Procedur álne programovanie: 6 . prednáška

Definícia a inicializácia reťazca

char s[15] = "abrakadabra";

char s[10];s = "ahoj";

char *s = "ahoj";

pridá na koniec '\0'

tu s nepredstavuje dynamickýreťazec, ale ukazovateľ na typ char a je inicializovaný adresou konštanty (pre ktorú je vyhradené miesto)

v C nie je možné takto priradiť statickému reťazcu konštantu

Page 46: Procedur álne programovanie: 6 . prednáška

Inicializácia dynamického reťazca?

• dynamicky vytvorený reťazec sa nedá inicializovať!

char *s;s = (char *) malloc(10);s = "ahoj";char c;int i=0;while ((c=getchar()) != '\n' && i < 9) s[i++] = c;s[i] = '\0';

alokovanie 10 znakov do s

načítanie aj pomocou scanf

Page 47: Procedur álne programovanie: 6 . prednáška

Poznámky k definícii a inicializácii reťazcov

• definícia typu pre reťazce

• treba rozlišovať:– nulový ukazovateľ NULL a nulový reťazec '\0':

• nulový ukazovateľ neukazuje na žiadne miesto v pamäti, • nulový reťazec má v 0-tom prvku znak '\0'

– "x" a 'x':• "x" je reťazec s jedným znakom ukončený '\0' (2 Byty)• 'x' je jeden znak (1 Byte)

typedef char *STRING;

Page 48: Procedur álne programovanie: 6 . prednáška

Čítanie reťazca z klávesnice

• scanf() vynecháva biele znaky a číta po prvý biely znak

• ak je na vstupe " ahoj Eva!", scanf() prečíta iba "ahoj" a zvyšok zostáva v bufferi klávesnice

char s[10];...scanf("%s", s);

sem nepartrí &, pretože s je adresa

Page 49: Procedur álne programovanie: 6 . prednáška

Formátované čítanie: príklad

Program vypočíta celkovú sumu peňazí zo súboru, kde jednotlivé

sumy sú vždy uvedené znakom $ a znamienko + je pre

príjem a - pre výdaj

Príklad súboru: + $10 -$5- $8 +$20

Page 50: Procedur álne programovanie: 6 . prednáška

Formátované čítanie: príklad

include <stdio.h>

void main() { FILE *f; int kolko, suma = 0; char akcia[2];

f = fopen("peniaze.txt", "r"); while (fscanf(f, "%1s", akcia) != EOF) { fscanf(f, "$%d", &kolko); suma += (akcia[0] == '+') ? kolko : (-1*kolko); } printf("Spolu: %d\n", suma); fclose(f);}

namiesto %1s nemôže byť %c, pretože by prečítal medzeru, nie prvý znak

podobne $%d: $ zabezpečuje, že sa preskočia biele znaky

Page 51: Procedur álne programovanie: 6 . prednáška

Výpis reťazca na obrazovku: pomocou statického reťazca

printf("%s", s);

include <stdio.h>void main() { char str[11];

printf("Zadaj retazec: "); scanf("%s", str); printf("Retazec je: %s \n", str);}

scanf("%10s", s);

vypísanie načítaného reťazca

str má 10 znakov, preto je vhodné použiť:

Page 52: Procedur álne programovanie: 6 . prednáška

Výpis reťazca na obrazovku: pomocou dynamického reťazca

include <stdio.h>

void main() { char *str;

if((str = (char *) malloc(11)) == NULL) return;

printf("Zadaj retazec: "); scanf("%s", str); printf("Retazec je: %s \n", str);}

Page 53: Procedur álne programovanie: 6 . prednáška

Prístup k jednotlivým znakom reťazca

• reťazec = jednorozmerné pole znakov• pracuje sa s ním ako s

jednorozmerným poľom

char s[10];

for (i = 0; i < 10-1; i++) s[i] = '*';s[10-1] = '\0';

po znakoch naplní reťazec hviezdičkami

dôležité: ukončiť reťazec!

Page 54: Procedur álne programovanie: 6 . prednáška

Štandardné funkcie pre prácu s reťazcami

• nie sú súčasťou samotného jazyka C

• sú definované v <string.h>

Page 55: Procedur álne programovanie: 6 . prednáška

Štandardné funkcie pre prácu s reťazcami

int strlen(char *s);

char *strcpy(char *s1, char *s2);

char *strcat(char *s1, char *s2);

pripojí reťazec s2 k s1, vracia ukazovateľ na s1

kopírovanie reťazca s2 do s1, vracia ukazovateľ na s1

vracia dĺžku reťazca (bez \0)

Page 56: Procedur álne programovanie: 6 . prednáška

Štandardné funkcie pre prácu s reťazcami

int strcmp(char *s1, char *s2);

char *strstr(char *s1, char *s2);

char *strchr(char *s, char c);

nájdenie znaku c v reťazci s, vracia prvý výskyt znaku, ak sa v s nenachádza, vráti NULL

vracia 0, ak sú reťazce rovnaké, záporné číslo, ak s1 je menšie, inak kladné číslo

vracia ukazovateľ na prvý výskyt reťazca s2 v reťazci s1, v prípade neúspechu NULL

Page 57: Procedur álne programovanie: 6 . prednáška

Príklad: prekopírovanie reťazca znakov

...

char c, *s1, s2[]="ahoj";int i=0;s = (char *) malloc(10);

while (s2[i] != '\0') s1[i] = s2[i++];s1[i] = '\0';

strcpy(s1, s2);

#include <string.h>

Page 58: Procedur álne programovanie: 6 . prednáška

Príklad: hľadanie podreťazca

Program vypíše indexy všetkých výskytov podreťazca v reťazci

Page 59: Procedur álne programovanie: 6 . prednáška

#include <stdio.h>#include <string.h>#define N 50

int main() { char s[N], pod[N], *p_s = s, *p;

printf("Zadajte retazec: "); scanf("%s", s); printf("Zadajte podretazec: "); scanf("%s", pod);

while ((p = strstr(p_s, pod)) != NULL) { printf("Podretazec je na %d. indexe.\n", p - s); p_s = p + 1; }

if (p_s == s) printf("\"%s\" sa v \"%s\" nenachadza.\n", pod, s); return 0;}

Page 60: Procedur álne programovanie: 6 . prednáška

Príklad: porovnávanie reťazcov

char x[10], y[10];int r;

if ((r = strcmp(x, y)) == 0) printf("Retazce \"%s\" a \"%s\" sa rovnaju\n", x, y);else if (r < 0) printf("Retazec \"%s\" < retazec \"%s\"\n", x, y);else printf("Retazec \"%s\" < retazec \"%s\"\n", y, x);

Časť programu zistí, či sa reťazce rovnajú, prípadne, ktorý je neskôr v

abecede.

Page 61: Procedur álne programovanie: 6 . prednáška

Práca s obmedzenou časťou reťazca

• podobne ako uvedené funkcie,

• v názve je n (zo slova number), napr. strncpy():

char *strncpy(char *s1, char *s2, int max);

kopírovanie najviac max znakov z reťazca s2 do s1,vracia ukazovateľ na s1

Page 62: Procedur álne programovanie: 6 . prednáška

Príklad: kopírovanie časti reťazcov

Prekopírovanie názvu a prípony súboru do dvoch reťazcových premenných

Page 63: Procedur álne programovanie: 6 . prednáška

...char subor[20], *p_bodka, nazov[10], pripona[10];

printf("Zadajte nazov subor: ");scanf("%s", subor);

p_bodka = strchr(subor, '.'); /* najdenie bodky */if ( p_bodka == NULL) { strcpy(nazov, subor); pripona[0] = '\0';}else { strncpy(nazov, subor, p_bodka - subor); nazov[p_bodka - subor] = '\0';

p_bodka++; /* posun za bodku */ strncpy(pripona, p_bodka, strlen(p_bodka) + 1);}

printf("nazov: %s, pripona: %s\n", nazov, pripona); printf("%d", p_bodka - subor); return 0;

Page 64: Procedur álne programovanie: 6 . prednáška

Práca s reťazcom naopak

• podobne ako uvedené funkcie,

• v názve je r (zo slova reverse), napr. strrchr():

char *strchr(char *s, char c);

nájdenie znaku c v reťazci s, vracia posledný výskyt znaku, ak sa v s nenachádza, vráti NULL

Page 65: Procedur álne programovanie: 6 . prednáška

Príklad: zistenie pozície znaku odzadu

...char s[100], *p;

if ((p = strrchr(s, '*')) != NULL) printf("Posledna '*' je na pozicii: %d\n", p - s);else printf("'*' sa v retazci nenachadza.\n");

Zistenie pozície posledného znaku '*' v reťazci

Page 66: Procedur álne programovanie: 6 . prednáška

Prevody reťazcov na čísla

• konvertovanie reťazca číslic na číslo (funkcie definované v stdlib.h)

int atoi(char *s);

Pri vstupe a výstupe nie je konverzia potrebná (scanf() a printf())

long atol(char *s);

float atof(char *s);

prekonvertuje reťazec znakov na int

prekonvertuje reťazec znakov na float

prekonvertuje reťazec znakov na long

Page 67: Procedur álne programovanie: 6 . prednáška

Príklad: kopírovanie časti reťazcov

char s1[100], s2[100];int i;

scanf("%s %s", s1, s2);if (!strcmp(s1, "int")) { i = atoi(s2); printf("Nacitalo sa cele cislo: %d\n", i);}else { printf("Nacital sa retazec znakov: %s\n", s2);}

ak je prvý načítaný reťazec "int", druhý reťazec predstavuje číslo -

prekonvertuje sa na číslo

Page 68: Procedur álne programovanie: 6 . prednáška

Formátovaný vstup a výstup z a do reťazca

• použitie výhod formátovaného vstupu a výstupu, ale netlačiť nič na obrazovku ani nenačítavať

int sprintf(char *s, char *format, ...);

int sscanf(char *s, char *format, ...);

pracuje ako fprintf, ale zapisuje do reťazca s

pracuje ako fscanf, ale číta z reťazca s

Page 69: Procedur álne programovanie: 6 . prednáška

Formátovaný vstup a výstup z a do reťazca: príklad 1

include <stdio.h>void main() { int i; char s1[5], s2[10];

printf("Zadaj 4 hexa cislice: ");

scanf("%s", s1); sscanf(s1, "%x, &i); sprintf(s2, "%o", i); printf("%s \n", s2);}

načíta 4 hexadec. číslice

číslice načíta do i

číslo i zapíše ako osmičkové do s2

Page 70: Procedur álne programovanie: 6 . prednáška

Formátovaný vstup a výstup z a do reťazca: príklad 2

void uradnik(char *s, double r) { double obsah, obvod;

obsah = 3.14 * r * r; obvod = 2 * 3.14 * r; sprintf(s, "Kruh s polomerom %f ma obsah %f a obvod %f \n", r, obsah, obvod);}

void sef(void) { char sprava[20];

uradnik(sprava, 5.0); printf("Sprava o kruhu je:\n %s", s);}

Page 71: Procedur álne programovanie: 6 . prednáška

Riadkovo orientovaný vstup a výstup z terminálu

• okrem scanf(), printf() aj:

char *gets(char *s);

int puts(char *s);

číta celý riadok do s: na koniec nezapíše \n, ale \0, vracia ukazovateľ na s, ak je riadok prázdny dáva do s \0 a vráti NULL

vypíše reťazec a odriadkuje (\n), vráti nezáporné číslo ak sa podarilo vypísať, inak EOF

Page 72: Procedur álne programovanie: 6 . prednáška

Riadkovo orientovaný vstup a výstup zo súboru

• okrem fscanf(), fprintf() aj:

char *fgets(char *s, int max, FILE *fr);

int fputs(char *s, FILE *fw);

číta riadok zo súboru do konca riadku ale maximálne max znakov, načítané zapíše do s (aj s \n), vracia ukazovateľ na s, ak je koniec súboru tak NULL

do súboru fw vypíše reťazec s, neodriadkuje ani neukončuje pomocou \0, vráti nezáporné číslo ak sa podarilo vypísať, inak EOF

Page 73: Procedur álne programovanie: 6 . prednáška

Príklad: riadkovo orientovaný vstup a výstup

Program načíta riadok zo súboru a riadok zo štandardného vstupu.

Načítané reťazce vypíše na obrazovku - každý do zvlášť riadku. Reťazec znakov vypíše do súboru a

na obrazovku a odriadkuje.

Page 74: Procedur álne programovanie: 6 . prednáška

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

int main() { FILE *f; char s[100];

/* citanie */ if((f = fopen("subor.txt", "r")) == NULL) { printf("Subor sa nepodarilo otvorit na citanie.\n"); return 1; } printf("%s", fgets(s, 100, f)); printf("%s\n", gets(s)); /* pridanie \n */

fclose(f);

Page 75: Procedur álne programovanie: 6 . prednáška

/* zapis */ if((f = fopen("subor_zapis.txt", "w")) == NULL) { printf("Subor sa nepodarilo otvorit na zapis.\n"); return 1; } fputs(s, f); fputs("\n", f); /* pridanie \n */ puts(s); fclose(f);

return 0;}

Príklad: riadkovo orientovaný vstup a výstup