Fizikus C labor

1. óra: ismerkedés a fejlesztőkörnyezettel2. óra: ciklusok3. óra: számelméleti feladatok
4. óra: számítás valós számokkal5. óra: sok adat beolvasása, tömbök6. óra: iteráció, könyvtári sztringkezelő függvények
7. óra: függvények és sztringek8. óra: cím szerinti és tömb paraméterek, struktúrák, dinamikus tömbök9. óra: rendezés, fájlkezelés, parancssori paraméterek
10. óra: állapotgép, szabványos I/O átirányítása11. óra: rekurzió, gyakorlás12. óra: láncolt listák, fák
13. óra: NHF beadás

Rajzoljunk a konzol ablakba Windowson

6. alkalom: iteráció, könyvtári sztringkezelő függvények

Nagy házi

1. feladat

Mennyi a 2x+3=exp(x) egyenlet megoldása? Számítsd ki iterációval! (Azaz: rendezd át az egyenletet x=f(x) alakra, adj x-nek pl. 0 kezdőértéket, és egy ciklusban számítsd ki x értékét f(x) kiszámításával, amihez x i-1. iterációban kapott értékét használod!) Más kezdőértéknél mi lesz az eredmény? Fejezd ki x-et másképp az eredeti egyenletből, és számítsd ki úgy is az iteráció értékét! Mit tapasztalsz?

2. feladat

Készíts függvényt, amely a paraméterként kapott nevet szétválasztja vezetéknévre és keresztnévre! A megoldáshoz használj könyvtári függvényeket!

Tippek:

- A bemeneti sztringet, valamint a két kimeneti sztring tárolására szolgáló két karaktertömböt paraméterként kapja a függvény.

- Az sscanf függvény segítségével egy sztringből olvashatsz ugyanúgy, ahogy a scanf függvénnyel a billentyűzetről (vagyis a szabványos bemenetről) teszed. Az sscanf első paramétere a sztring, amiből olvasunk. A %s az első whitespace karakterig olvas (szóköz, tabulátor, enter). Ezzel ki tudjuk olvasni a vezetéknevet. Azaz sscanf(nev,"%s",vezeteknev); kiolvassa a vezetéknevet.

- A sscanf(nev,"%s%s",vezeteknev,keresztnev); segítségével a vezetéknevet és az első keresztnevet tudjuk kiolvasni. Ha több keresztnév van, akkor az összeset a keresztnévbe szeretnénk tenni. (Ezt nem mondta ki a feladat, tehát ha ZH feladat lenne így, akkor a %s%s is elég volna.) A következő módszer bármennyi kersztnévre működik: (a) Kiolvassuk a vezetéknevet egy sscanf-fel. (b) Megkeressük az első szóközt az strchr-rel. (c) a szóköz utáni karaktertől a sztring végéig átmásoljuk a nevet a kersztnévbe az strcpy segítségével. Az strcpy egy sztringet másol át egy cél tömbbe egy forrás tömbből. Fontos, hogy az első paraméter a cél, a második a forrás. Pl. strcpy(keresztnev, szokoz+1); A +1 azért van ott, hogy ne a szóköztől kezdve másoljunk, hanem a szóköz utáni karaktertől.

3. feladat

Készíts függvényt, amely egy vezetéknevet és egy keresztnevet kap, és ezeket összefűzi egy sztringgé! A megoldást két változatban készítsd el:

a) A teljes nevet tároló karaktertömböt paraméterként kapja.

b) Dinamikus tömböt foglal az eredmény számára, és ennek a dinamikus tömbnek a címével tér vissza. A dinamikus tömböt a hívó függvényben (tipikusan a main-ben) fel kell szabadítani!

Tippek:

- A vezetéknevet strcpy-vel átmásoljuk a teljes név számára létrehozott tömbbe, majd strcat-tal a végére fűzzük a keresztnevet. Pontosabban még egy szóköz kell közéjük. Ezt is az strcat-tal fogjuk másolni. Vigyázat, az strcat csak sztringet tud másolni, egy karakterrt nem, ezért a szóköz számára létrehozunk egy sztringet. Így: strcat(nev, " ");

- Egy utasítással is megoldhatjuk a feladatot, ha a sprintf-et használjuk. Ez úgy működik, mint a printf, csak nem a képernyőre (szabványos kimenetre) ír, hanem egy sztringbe. Első paramétere a sztring. Azaz sprintf(nev,"%s "5", vezeteknev, keresztnev); A printf-ben szereplő %s nem csak whitespace karakterig ír ki, hanem a teljes sztringet kiírja.

- Ha dinamikus tömbbe tesszük az eredményt, akkor tudnunk kell, mekkora tömböt foglaljunk. Ez a vezetéknév és a kersztnév hossza, plusz a közéjük kerülő szóköz hossza (egy karakter) plusz a lezáró nulla (egy karakter). A lezáró nullát az strcpy, strcat, sprintf, stb. függvények automatikusan a sztring végére teszik, de a helyfoglalásnál ezzel foglalkoznunk kell. A szting hosszát az strlen függvénnyel tudjuk megállapítani. Így malloc(sizeof(char)*(strlen(vezeteknev)+strlen(keresztnev)+1+1)) a memóriafoglalás.

Az órai feladatok mintamegoldása

1. feladat
#include <stdio.h>
#include <math.h>

int main(){
	double elozo,x;

	elozo=x=0;
	do{
		elozo = x;
		x = log(2*x+3);
		//x = 0.5 * (exp(x) - 3.0);
	}
	while( fabs(elozo-x) > 0.00001);

	printf("%g\n",x);
	return 0;
}

 

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

void vez_ker_szetvalaszt(char nev[], char vez[], char ker[]) {
    sscanf(nev, "%s", vez);
    char * szokoz;
    szokoz = strchr(nev, ' ');
    if (szokoz != NULL)
        strcpy(ker, szokoz + 1);
    else
        ker[0] = '\0'; // Ha nincs keresztnév, akkor üres sztring.
}

int main() {

    char nev[100];

    fgets(nev, 100, stdin); // A sor végi ENTER-t is a név végére teszi. Mit lehet tenni ezzel?

    char *enter;
    if ((enter = strchr(nev, '\n')) != NULL)
        *enter = '\0'; // Töröljük a sor végi ENTER-t

    char vez[100], ker[100];
    vez_ker_szetvalaszt(nev, vez, ker);
    printf("Vezeteknev: %s, keresztnev: %s\n", vez, ker);

    vez_ker_szetvalaszt("Petofi Sandor", vez, ker);
    printf("Vezeteknev: %s, keresztnev: %s\n", vez, ker);

    return 0;
}

 

3. feladat
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void osszefuz_a(char vez[], char ker[], char nev[]) {
    strcpy(nev, vez);
    strcat(nev, " ");
    strcat(nev, ker);
}

char * osszefuz_b(char vez[], char ker[]) {
    char *nev = (char*)malloc(sizeof(char)*(strlen(vez) + strlen(ker) + 1 + 1));
    sprintf(nev, "%s %s", vez, ker);
    return nev;
}

int main() {

    char nev[100];

    osszefuz_a("Petőfi", "Sándor", nev);
    printf("%s\n", nev);

    char * dinnev = osszefuz_b("Arany", "János");
    printf("%s\n", dinnev);
    free(dinnev);

    return 0;
}