Karakterláncok és mutatók
Az alábbi kódokkal a mutatók használatának alapfokú alkalmazási lehetőségeit kívánom bemutatni. Ebben az esetben a mutatók a karakterláncok (karakterek egydimenziós tömbje) karakterpozícióinak (memóriacímének) megtalálására korlátozódnak. Ezzel a megoldással ellenőrizhetünk például fájlneveket vagy manipulálhatunk karakterláncokat, de a fájlok méretét is a mutatópozíciók alapján tudhatjuk meg.
Az első példakódban egy karakterláncot forgatunk el oly módon, hogy a forgatás mértékét és gyakoriságát is megadjuk. A forgat függvény egy elforgatott karakterlánccal tér vissza, argumentumként pedig az elforgatandó karakterláncot és az elforgatás mértékét kéri be. Jelen esetben ez utóbbi 3-ra definiált (#define F 3), ami azt jelenti, hogy a mutató az elforgatandó karakterlánc végére, egész pontosan a végétől számítva a harmadik karakter címére mutat. Ez a gyakorlatban azt jelenti, hogy az elforgatáshoz a karakterlánc végéről három karaktert leválaszt [*p >> strcpy(res,p)], majd az eléjéhez fűzi [strcat(res,s)]. Mivel itt több példányon keresztül, közvetett műveletekkel valósul meg a forgatás, a strcpy karakterlánc másoló függvényre többször is szükség van. A forgatás gyakoriságáról egy for ciklus gondoskodik a main függvényben, ennek száma példánkban szintén 3-ra definiált (#define N 3).
#include <stdio.h>
#include <locale.h>
#include <windows.h>
#define F 3
#define N 3
//karakterláncot elforgat
char *forgat(char s[], int f) {
int len = strlen(s);
char *p = &s[len - f];
char *res = (char*)malloc(len+1);
strcpy(res,p);
s[len - f] = '\0';
strcat(res,s);
strcpy(s, res); //átalakított legyen az eredeti helyén! <- globálisan megváltoztatja
return res;
}
int main() {
setlocale(LC_ALL, "Hungarian_Hungary.1250");
//karakterlánc elforgatása többször
char s[] = "HelloWorld";
printf("Elforgatandó szó: %s\nMennyivel: %d\nHányszor: %d\n\n", s,F,N);
int i;
for (i = 0; i < N; i++) {
char *forg = forgat(s, F);
printf("%d. Elforgatás: %s\n", i+1,forg);
free(forg);
}
return 0;
}
A fenti kódban megfigyelhető, hogy a forgat függvény visszatérése előtt az s karakterlánc felülírásra kerül [strcpy(s,res)], ezért a következő elforgatásnál a felülírt s fog rendelkezésre állni. Az is látható, hogy forgat függvény visszatérési értékének (res) memóriafoglalása a függvényen belűl történik, míg a felszabadítás a main függvényben. Ez utóbbit olyan függvények esetében alkalmazhatjuk, amelyek a visszatérési érték számára dinamikusan foglalják le a memóriát, pl. a malloc függvénnyel.
Az alábbi képen a program kimenete látható. A HelloWorld szót forgattuk el, három karakterrel és három alkalommal. Az első elforgatásnál látható, hogy a szó utolsó három karaktere “rld” a szó elejére kerül, megalkotva az “rldHelloWo” szót. Mivel az elforgatás összesen háromszor történik meg, ezért az eredetileg megadott szóból végül “elloWorldH” lesz.

A mutatók a C nyelvben nem csak karakterláncok manipulálására hanem validálására is alkalmasak. Az alábbi fval függvény ellenőrzi, hogy egy txt kiterjesztesű szöveges fájl neve megfelel-e az alapvető formai elvárásoknak. Ehhez csak arra van szükség, hogy igaz legyen: a fájlnév/karakterlánc utolsó három karaktere azonos a “txt” karakterlánccal. A *ptr mutató a strchr függvény segítségével a karakterlánc ‘.’ utáni pozícióját (valójában a memóriacímét) veszi fel, majd az itt elhelyezkedő “karakterlánc-töredéket” hasonlítja össze a megadott kiterjesztéssel, esetünkben a “txt”-vel. Az összehasonlításhoz a strcmp függvényt hívja meg.
#include <stdio.h>
#include <locale.h>
#include <windows.h>
//fájlnév érvényesség
int fval(char *s, char *kit) {
char *ptr = strchr(s, '.') + 1;
if (strcmp(ptr, kit) != 0)
return 1;
return 0;
}
int main() {
//magyar nyelvű konzol
setlocale(LC_ALL, "hun");
char *fnev = "pelda.txt", *kit = "txt";
printf("Ellenőrzi, hogy a fájlnév %s kiterjesztésű-e?\n", kit);
if (fval(fnev, kit) == 0)
printf("A %s: Helyes fájlnév!\n", fnev);
else
printf("A %s: Helytelen fájlnév\n", fnev);
return 0;
}
Az alább látható konzol képeken egy helyes illetve egy hibás bemenet kiértékelése látható.


A mutatóknak a fájlok olvasása, írása esetén is szerepe van. Amikor C-ben megnyitunk egy fájlt, akkor egy úgynevezett fájlmutatót definiálunk. Ez látható az alábbi kódrészletben.
FILE *fp;
fp = fopen("teszt.txt","r");
if(!fp){
perror("");
return fp;
}
/* Műveletek fájlokkal */
fclose(fp);
Az alábbi példa egy fájl méretet meghatározó C függvény, amely a mutatót fájl végére pozícionálja és visszatér ezzel az értékkel (res). A függvény a visszatérés előtt visszaállítja a fájlmutató eredeti pozícióját (pos), így a program a továbbiakban innen folytathatja a fájlon végzendő műveleteket. A res egy lebegőpontos érték, ami a fájl bájtokban vett mérete. Példánkban azonban a definiált váltószám 1024, tehát a függvény visszatérési értéke kilobájtban értendő.
#define VALTO 1024
//fájlméret
float fmeret(FILE *fp) {
float res;
int pos = ftell(fp);
fseek(fp, 0L, SEEK_END);
res = (float)ftell(fp);
fseek(fp, pos, SEEK_SET);
return res /VALTO;
}