5.1. Összetett adatszerkezetek
Stringek
A string típusú változók néhány tulajdonságát már megismerhettük a mobilszám-ellenőrző programban. A C#-ban, mint objektumorientált nyelvben a string nem csak típus, hanem osztály is. Az egy típusba tartozó változókat, a hozzájuk tartozó műveleteket és operátorokat osztálynak nevezzük.
A string osztályhoz tartozó műveletek közül már ismerünk kettőt a fent említett programból:
- Szöveghossz meghatározása: A
szam.Lengthmegadta aszamstring hosszát, aszam[0].ToString()pedig a szöveg 1. karakterét. - Összeadás: Fontos megemlíteni, hogy az összeadás művelet értelmezhető stringeken, de eredménye nem azonos a számtípusoknál megismerttel. Itt a szövegeket egymás után fűzi a
+operátor. Pl.:"objektum" + "orientált" = "objektumorientált", ami talán nem meglepő, de számokból álló stringek esetén már érdekesebb, mert:"77" + "23" = "7723"lesz. - Összehasonlítás: A stringek 1 karakterére értelmezhető a
<és a>jel ebben a formában:szoveg[4] > szoveg[1]. A teljes stringre viszont csak az==, vagy!=relációs jelek értelmezhetők.
Természetesen a C# nem lenne magas szintű programozási nyelv, ha ilyen hiányosságban szenvedne. A CompareTo segítségével a teljes stringre is tudjuk alkalmazni a kisebb/nagyobb relációkat. A következő feladat ezt mutatja be.
45. feladat
Kérjünk be két szöveget és írassuk ki a képernyőre az ABC-ben előbb lévőt, majd alá az ABC-ben hátrébb levőt! Név: Szövegrendezés
Megoldás:
static void Main(string[] args)
{
string szoveg1, szoveg2;
Console.WriteLine(" Kérem az 1. szöveget:");
szoveg1 = Console.ReadLine();
Console.WriteLine(" Kérem a 2. szöveget:");
szoveg2 = Console.ReadLine();
Console.WriteLine(" ABC sorrendben:");
// A CompareTo() metódus összehasonlítja a két stringet
if (szoveg1.CompareTo(szoveg2) > 0)
{
Console.WriteLine("1. {0}", szoveg2);
Console.WriteLine("2. {0}", szoveg1);
}
else
{
Console.WriteLine("1. {0}", szoveg1);
Console.WriteLine("2. {0}", szoveg2);
}
Console.ReadKey();
}
Két string összehasonlításakor 3 eset lehetséges:
- Ha
szoveg1 > szoveg2, vagyisszoveg1később van az ABC-ben, akkor aszoveg1.CompareTo(szoveg2) = 1 - Ha
szoveg1 < szoveg2, vagyisszoveg1előbb van az ABC-ben, akkor aszoveg1.CompareTo(szoveg2) = -1 - Ha
szoveg1 == szoveg2, akkor aszoveg1.CompareTo(szoveg2) = 0
További szöveges műveletek
- Levágás: A levágás a
Trim(), aTrimStart()és aTrimEnd()segítségével jön létre. Ha a zárójelek közé nem írunk paramétereket, akkor aTrim()levágja a szöveg elejéről és végéről, aTrimStart()csak az elejéről, aTrimEnd()csak a végéről a szóközöket. Ha aszovegegy string típusú változó, akkor aszoveg.Trim('b');levágja a szöveg elejéről és végéről az összes 'b' karaktert. - Átalakítás (kisbetű - nagybetű): Átalakítani nagybetűkké a
ToUpper(), kisbetűkké aToLower()segítségével lehet. Pl.: Haszoveg = "félév", akkor aszoveg.ToUpper();után a szöveg"FÉLÉV"lesz. - Másolás: Egy szövegből tetszőleges részt másolhatunk a
Substring(kezd, db)segítségével, ahol akezdés adbegész típusú változók és a sztringből a kezd karaktertőldbdarab karaktert másolhatunk ki. Ha a zárójelek között csak egy paraméter van, akkor a kezd értéktől egészen a szöveg végéig másolhatunk ki részsztringet. Hasz = "Paróka", akkorsz.Substring(2) = "róka". Ne felejtsük el, hogy itt is 0-tól kezdjük a sztring karaktereinek számozását, mint a tömböknél. - Keresés: Az
IndexOf()függvénnyel megtudhatjuk, hogy az adott karakter vagy karaktersorozat szerepel-e a sztringben, és ha igen, hol. Ha benne van, akkor a függvény értéke 0 vagy pozitív, ha nincs benne, akkor -1 lesz. Ha a függvény értéke nem -1, akkor a kapott érték azt mutatja meg, hogy hányadik karaktertől találjuk meg az adott karaktersorozatot a szövegben. Pl.: Ha aszoveg.IndexOf(szo) = 3, akkor aszovegszövegben aszoszó a 4. pozíciótól található meg. (Pl:szoveg = "M á t é s z a l k a"ésszo = "é s z").
46. feladat
Kérjünk be egy szöveget és egy karaktert majd írjuk ki, hogy a szövegben hányszor fordul elő a megadott karakter! Név: Karakterszamlalas
Megoldás:
static void Main(string[] args)
{
string szoveg;
char karakter = ' ';
int db = 0, i = 0;
Console.Write(" Kérem a szöveget: ");
szoveg = Console.ReadLine();
Console.Write(" Kérem a karaktert: ");
karakter = Convert.ToChar(Console.ReadLine());
for (i = 0; i < szoveg.Length; i++)
{
if (karakter == szoveg[i]) db++;
}
Console.WriteLine();
Console.WriteLine(" A(z) {0} karakterből {1} db van a szövegben", karakter, db);
Console.ReadKey();
}
Mivel csak szöveget lehet bekérni billentyűről, ezért a k (karakter) bekérésénél karakterré kell konvertálni.
47. feladat
Kérjünk be egy szöveget és egy szót majd írjuk ki, hogy a szövegben hányszor fordul elő a megadott szó! Név: Szoszamlalas
Megoldás:
static void Main(string[] args)
{
string szoveg, szo;
int db = 0, i = 0;
Console.Write(" Kérem a szöveget: ");
szoveg = Console.ReadLine();
Console.Write(" Kérem a szót: ");
szo = Console.ReadLine();
for (i = 0; i <= szoveg.Length - szo.Length; i++)
{
if (szoveg.Substring(i, szo.Length) == szo) db++;
}
Console.WriteLine();
Console.WriteLine(" A(z) {0} szóból {1} db van a szövegben", szo, db);
Console.ReadKey();
}
A for ciklus a szót a szövegben a 0. karaktertől kezdve keresi a szöveg hossza - szó hossza értékig. Ha tehát a szöveg 10 hosszú, a szó pedig 3, akkor 10 - 3 = 7 lesz az i végértéke, tehát 0-tól 7-ig 8-szor fut le a ciklusmag. Utoljára az szoveg.Substring(7,3) értékét hasonlítjuk össze a szóval, vagyis a szöveg 7., 8., 9. karakterét hasonlítjuk a 3 hosszúságú szóval és ha megegyezik, akkor növeljük db értékét.
48. feladat
Kérjünk be egy szöveget, és írjuk ki visszafelé! A fordított szöveg csak nagybetűből álljon! Név: Szovegmegfordito
Megoldás:
static void Main(string[] args)
{
string szoveg = "", forditottSzoveg = "";
int i = 0;
Console.Write(" Kérem a szöveget: ");
szoveg = Console.ReadLine();
for (i = szoveg.Length - 1; i >= 0; i--)
{
forditottSzoveg = forditottSzoveg + szoveg[i];
}
Console.WriteLine(" A szöveg megfordítva: ");
Console.WriteLine(forditottSzoveg.ToUpper());
Console.ReadKey();
}
A for ciklust most a szöveg vége - 1-től 0-ig visszafelé kell léptetni és az új, megfordított szöveghez egyesével kell hozzáfűzni az aktuális, 1 hosszúságú szöveget.
49. feladat
Kérjük be egy személy nevét, amely vagy 2 vagy 3 részből áll! Írjuk ki a vezetéknevet, majd alá a keresztnevet és ez alá a második keresztnevet, ha van! Név: Nevkiiras
Megoldás:
static void Main(string[] args)
{
string nev = "", vNev = "", kNev = "", k2Nev = "";
int i = -1;
Console.WriteLine(" Kérem a nevet: ");
nev = Console.ReadLine();
do
{
i++;
vNev = vNev + Convert.ToString(nev[i]);
} while (nev[i] != ' ');
Console.WriteLine(" A vezetéknév: {0}", vNev);
do
{
i++;
kNev = kNev + Convert.ToString(nev[i]);
} while (nev[i] != ' ' && i + 1 != nev.Length);
Console.WriteLine(" A keresztnév: {0}", kNev);
if (nev[i] == ' ')
{
do
{
i++;
k2Nev = k2Nev + Convert.ToString(nev[i]);
} while (i < nev.Length - 1);
Console.WriteLine(" A 2. keresztnév: {0}", k2Nev);
}
Console.ReadKey();
}
A program megírásánál abból indulunk ki, hogy a neveket szóköz választja el egymástól. Ha egy szóköz van a szövegben, akkor csak vezeték- és keresztnév van, ha két szóköz, akkor második keresztnév is van. Ezért a név bekérése után egy hátultesztelő ciklusban addig tesszük a szöveg karaktereit a vNev változóba, amíg az 1. szóközig elérünk. Ekkor már a vezetéknevet ki is írjuk a képernyőre.
A szövegben továbbhaladva a keresztnevet kapjuk meg. Addig kell a ciklusban maradni, amíg két feltétel egyszerre teljesül:
1. nev[i] != ' ' vagyis a szöveg aktuális karaktere nem egyenlő szóközzel és
2. i + 1 != nev.Length tehát a következő karakter sorszáma nem az utolsó a szövegben.
Nézzük fordítva: Kiléphetünk a ciklusból, ha szóközhöz érünk – ekkor nem teljesül az első feltétel –, vagy ha a szöveg utolsó karakteréhez értünk. Ha szóköz volt a szövegben, akkor egy újabb ciklusban előállítjuk a 2. keresztnevet és kiírjuk, ha nem, befejezzük a programot.
Ellenőrző kérdések
Mi lesz az alábbi szövegfüggvényekkel végzett műveletek eredménye?
- Ha
sz = "süveges";akkorsz.Trim('s')= ....... - Ha
sz = "Messi a messiás";akkorsz.IndexOf("si")= ....... - Ha
sz = "Paróka";akkorsz.Substring(2,2)= ....... - Ha
sz = "Ouagadougou";akkorsz.Substring(8)= .......
Kattints ide a megoldásért!
- Ha
sz = "süveges";akkorsz.Trim('s')= "üvege" (Levágja az 's' betűket az elejéről és a végéről) - Ha
sz = "Messi a messiás";akkorsz.IndexOf("si")= 3 (A "si" karaktersorozat a 0-tól indexelt szöveg 3. indexén kezdődik a "Messi" szóban) - Ha
sz = "Paróka";akkorsz.Substring(2,2)= "ró" (A 2-es indextől - ami az 'r' - számítva kivág pontosan 2 karaktert) - Ha
sz = "Ouagadougou";akkorsz.Substring(8)= "gou" (A 8-as indextől - ami a 'g' - a string legvégéig mindent kivág)