Szövegek C++ -ban, a string osztály A string osztály a Szabványos C++ könyvtár (Standard Template Library) része és bár az objektum-orientált programozásról, az osztályokról, csak később esik szó, a string osztály használatát már most elkezdhetjük. Az osztály bemutatásánál csak kódrészletet használunk, de a file végén teljes mintaprogramok találhatók. A string típus (osztály) használatához a string include file-t kell „betölteni”. Ha egy string adattal akarunk valamilyen műveletet végezni akkor a kovetkező formát kell használni: stringváltozó.művelet(argumentumok) Egy szöveget lehet inicializálni a C nyelvnek megfelelően, de egyéb speciális módok is léteznek: #include <string> ... { string string string string string
s0 ; // üres szöveg s00 = ""; // szintén üres szöveg s1 = ’a’; // HIBA: nincs konverzió karakterből s2 = 7 ; // HIBA: nincs konverzió egész számból s3(7); // HIBA: nincs konstruktor egész számmal
// exotikusabb szöveg megadások // --------------------------------------------------// ’a’ karakter másolata 7-szer; vagyis "aaaaaaa" string s4(7 ,’a’); string s5 = "Frodo"; // "Frodo" másolata kerül bele string s6 = s5; // s5 másolata lesz // s5[3] és s5[4]; vagyis s7 == "do" string s7(s5, 3, 2); A szövegben előforduló karakter számozása nullával kezdődik és a hossz-1 –ig tart. Az utolsó karakternek nem kell zérusnak lennie mint a C nyelvben, az osztály tudja magáról hogy milyen hosszú. A hossz megállapítására a length() vagy a size() függvény alkalmas. A szövegben egy karaktert többféleképpen érhetünk el, at() függvénnyel vagy hagyományos módon, két szögletes zárójel között [ ] . A fő különbség, hogy az at() függvény használata biztonságosabb, mivel a függvény ellenőrzi hogy az elérni kívánt karakter indexe érvényes-e. Ha nem érvényes indexet adunk meg akkor az osztály egy kívételt dob. (Ez most még csak annyit jelent hogy hibával leáll a program.)
Az értékadás szövegeknél is működik, bár az értékadásnál a jobb oldali szöveg átmásolódik a bal oldali szövegbe! { string s1 = ”Alma”; string s2 = ”ToT”; s1 = s2; // átmásoljuk a ToT szöveget s2[1] = ’u’; // s2 értéket: TuT, de s1 értéke: ToT } Karaktert is használhatunk az értékadásnál, de inicializálásnál nem! {
}
string s = ’a’; //HIBA: karakterrel nem lehet s = ’a’; s = ”a”; s = s;
Kétféle módon lehet egy string objektumot C-s szöveggé konvertálni, a data() és a c_str() függvényekkel. A data() függvény lényegében azt csinálja, hogy a string osztályban levő szöveget egy belső tömbbe másolja és ennek a tömbnek a címét adja vissza a függvény. Ezt tömböt a felhasználónak nem szabad felszabadítania! A c_str() függvény annyiban különbözik, hogy a tömb végére beilleszti a zérus karaktert is míg a data() függvény nem. Nézzünk néhány példát: { string s=”123456”; // hossza: s.length() == 7 // p a karaktersorozatra mutat const char *p1 = s.data(); p1[1] = ’a’; // HIBA: mivel a p1 tömb konstans // HIBA: mivel nincs záró zérus ’\0’ karakter printf(”p1 = %s\n”, p1); // a helyes módszer ebben az esetben const char *p2 = s.c_str(); printf(”p2 = %s\n”, p2); } A fenti példa alapvetően azt is jelenti, hogy inkább a c_str() függvényt használjuk. Egy másik tanács, hogy ameddig lehet inkább hagyjuk a szöveget a string osztályban, és csak ha nagyon kell akkor konvertáljuk C –s karakter lánccá. { string s = ”123”;
int i = atoi(s.c_str()); ... A szövegek összehasonlítása igen egyszerű, mert csak a relációs operátorokat kell használni: >, <, ==, !=, <=, >=. Ugyanakkor létezik egy compare() függvény is melynek a függvény overloading-nak köszönhetően nagyon sokféle változata van. Fontos, hogy mind a két módszer a kis és a nagy betűk között különbséget tesz! A szövegek összefűzésére a + vagy a += operátor használható: { string nev = ”Ivanyi”; nev = nev + ’ ’; nev += ”Peter”; Ezen kívül használható az insert() és az append() függvény is szöveg beillesztésére és szöveg összefűzésre. Ugyanakkor fontos arra emlékezni, hogy a függvények használata általában memória foglalást és memória másolást is igényel. Például ha rossz sorrendben állítjuk össze a nevet: { string nev = ”Peter”; s.insert(s.begin(), ’ ’); s.insert(0, ”Ivanyi”); Nagyon sokféle kereső függvény áll rendelkezésre az osztályban, de nézzünk csak egy egyszerűt: { string s=”abcdefg”; int i=s.find(”cd”); // Az eredmény: // i = 2 // mivel: // s[2] == ’c’ && s[3] == ’d’ A szöveg egy részének lecserélésére a replace() függvény alkalmas. Itt is a könnyebség kedvéért különböző méretű szövegeket lehet lecserélni. Egy rész szöveg meghatározására a substr() függvény alkalmas. { string s=”abcdefghijk”; cout << s.substr(0, 2); // ”ab”
Mintapéldák 1. Szövegek inicializálása és egymáshoz rendelése #include <string> using namespace std; int main() { string string1("Hello World"); string string2; // üres szöveg: ”” cout << string1 << ”-” << string2 << endl; string2 = string1; cout << string1 << ”-” << string2 << endl; // C-s szöveg hozzárendelése string2 = "Hello world"; cout << string1 << ”-” << string2 << endl; }
return 0;
2. Konverzió C –s karakter sorozattá #include
#include <string> using namespace std; int main() { string string1("Hello World"); // a pointernek konstansnak kell lennie // erre még visszatérünk char const *cString = string1.c_str(); // C –s szöveget így is ki lehet nyomtatni ! cout << cString << endl; return 0; }
3. Szöveg elemeinek elérése #include #include <string> using namespace std; int main() { string string1("Hello World"); cout << string1 << endl; string1[6] = 'w'; cout << string1 << endl; if(string1[0] == 'H') string1[0] = 'h'; cout << string1 << endl;
// "Hello world" // "hello world"
// *string1 = 'H'; // Ez érvénytelen !!! string1 = "Hello World"; cout << string1 << endl; string1.at(6) = string1.at(0); // "Hello Horld" cout << string1 << endl; if(string1.at(0) == 'H') string1.at(0) = 'W'; // "Wello Horld" cout << string1 << endl; return 0; }
4. Szövegek összehasonlítása #include #include <string> using namespace std; int main() { string string1("Hello World"); string string2; if(string1 != string2) string2 = string1; if(string1 == string2) string2 = "Something else"; if(string1.compare(string2) > 0)
cout << "string1 a string2 utan van az ABC-ben\n"; else if(string1.compare(string2) < 0) cout << "string1 a string2 elott van az ABC-ben\n"; else cout << "Azonos szövegek\n"; // Vagy másképpen: if(string1 > string2) cout << "string1 a string2 utan van az ABC-ben\n"; else if(string1 < string2) cout << "string1 a string2 elott van az ABC-ben\n"; else cout << " Azonos szövegek \n"; }
return 0;
5. Részszövegek összehasonlítása A compare függvény egyik változata: string1.compare(pos, n, string2) ahol a pos érték adja meg hogy a string1 szövegben hányadik karaktertől indul az összehasonlítás, az n érték határozza meg, hogy hány darab karaktert vegyünk figyelembe és string2 a másik szöveg amivel a string1-et összehasonlítjuk. #include #include <string> using namespace std; int main() { string stringOne("Hello World"); // bizonyos offset-től kezdve végezzük az // összehasonlítást if (!stringOne.compare(1, stringOne.length() - 1, "ello World")) cout << "'Hello world' osszehasonlitasa 1 indextol" " az 'ello World' szoveggel: ok\n"; else cout << "Nem egyenlo\n" }
return 0;
6. Szövegek összefűzése #include #include <string> using namespace std; int main() { string stringOne("Hello"); string stringTwo("World"); stringOne += " " + stringTwo; cout << stringOne << endl; stringOne = "hello"; stringOne.append(" world"); // csak 5 karaktert fuz hozza !!! stringOne.append(" ok. >Ez bizony kimarad<", 5); cout << stringOne << endl; string stringThree("Hello"); // hozzafuzzuk a " world" szot // 5. poziciotol 6 karakter stringThree.append(stringOne, 5, 6); cout << stringThree << endl; return 0; }
7. Szövegek beillesztése Az insert függvény egyik változata: string1.insert(pos1, string2, pos2, n2) ahol a pos1 érték adja meg hogy a string1 szövegben hányadik karaktertől indul a beillesztés, a string2 adja meg hogy melyik szövegből vesszük ki a beillesztendő szöveget, a pos2 érték adja meg hogy a string2 szövegben hányadik karaktertől vesszük ki a szöveget és az n2 érték határozza meg, hogy hány darab karaktert vegyünk ki a string2 szövegből.
#include <string> int main() { string stringOne("Hell ok."); // az "o " beillesztése a 4. pozícióba stringOne.insert(4, "o "); string world("The World of C++"); // a "World" beillesztése a stringOne -ba stringOne.insert(6, world, 4, 5); cout << "Mi az eredmény? Ez: " << stringOne << endl; return 0; }
8. Szövegek cseréje Az alábbi egy olyan program melyet két argumentummal kell elindítani, majd szövegeket kell begépelni. A program a begépelt sorokban az első argumentumban megadott szöveget keresi és lecseréli a második argumentumban megadott szövegre. A program a megváltoztatott sort nyomtatja ki. #include #include <string> #include using namespace std; int main(int argc, char **argv) { if(argc != 3) { cout << "Felhasznalas: "<< endl; cout << "program " << endl; cout << "A begepelt szovegben a szoveget" "lecsereli -ra" << endl; return 1; } string line; // ezt a szöveget keressük string search(argv[1]); // erre fogjuk lecserélni a keresett szöveget string replace(argv[2]); // meggyőződünk arról, hogy a régi és az új szöveg // nem azonos assert(search != replace);
// olvasunk amíg véget nem ér while(getline(cin, line)) { // ez a pozíció a beolvasott sorban string::size_type idx = 0; while(true) { // az idx pozíciótól keressük a szöveget // a visszatérési érték is index lesz idx = line.find(search, idx); // ha a sor végére értünk, akkor // nem találtuk meg a szöveget if (idx == string::npos) break; // végrehajtjuk a cserét line.replace(idx, search.size(), replace); // az indexet is módosítjuk, // a cserélt szöveg utánra állítjuk idx += replace.length(); }
} }
// kiírjuk a módosított sort cout << line << endl;
return 0;
9. Rész szövegek képzése #include #include <string> using namespace std; int main() { string stringOne("Hello World"); cout << stringOne.substr(0, 5) << stringOne.substr(6) << stringOne.substr() return 0; }
<< endl << endl << endl;
10. Szöveg hossza #include #include <string> using namespace std; int main() { string stringOne("Hello World"); cout << "A stringOne string hossza " << stringOne.size() << " karacter\n"; return 0; }