C++-ohjelmoinnin aloittaminen

Merkkijonot


Pythonin merkkijonotyyppi (str) kuuluu muuttumattomiin tietotyyppeihin. Merkkijonon sisältämää tekstiä ei voi muuttaa suoraan.

def main():
    teksti = "abcdefg"
    print(teksti[3])  # Tulostuu: d
    teksti[3] = "X"   # VIRHE!
    print(teksti)

main()

Pythonissa muokattu teksti muodostetaan luomalla uusi merkkijono ja sijoittamalla se samaan muuttujaan:

def main():
    teksti = "abcdefg"
    print(teksti[3])  # Tulostuu: d
    teksti = teksti[:3] + "X" + teksti[4:]
    print(teksti)     # Tulostuu: abcXefg

main()

C++:ssa olemassa olevaa merkkijonoa voi muuttaa, ellei sitä ole määritelty vakioksi (const string):

#include <iostream>
#include <string>  // string on kirjastotyyppi

using namespace std;

int main() {
    string teksti = "abcdefg";
    cout << teksti.at(3) << endl;  // Tulostuu: d
    teksti.at(3) = 'X';            // char-tyyppinen arvo
    cout << teksti << endl;        // Tulostuu: abcXefg
}

Sekä Pythonissa että C++:ssa merkkijonon indeksointi alkaa nollasta. C++:ssa merkkijonon yksittäiset merkit ovat char-tyyppisiä. teksti.at(indeksi) palauttaa char-arvon, ja siihen voi sijoittaa vain char-tyyppisen arvon.

Merkkijonoihin kohdistuvat nimetyt operaatiot ovat C++:ssa metodeja, kuten Pythonissakin. Metodeja kutsutaan muodossa muuttuja.metodi(parametrit):

#include <iostream>
#include <string>

using namespace std;

int main() {
    string teksti = "One string to rule them all...";
    cout << teksti.length() << endl;
    cout << teksti.substr(4, 14) << endl;
    teksti.replace(4, 6, "thing");
    cout << teksti << endl;
}

Jotkin merkkijonometodit palauttavat lukuarvoja, esimerkiksi merkkien määrän tai löydetyn merkkijonon indeksin. Näitä arvoja varten käytetään tyyppiä string::size_type:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string nimi = "";
    string::size_type apu = 0;

    cout << "Syötä nimesi: ";
    getline(cin, nimi);

    apu = nimi.length();
    cout << "Nimessa " << apu << " kirjainta" << endl;

    apu = nimi.find("nen");
    if (apu == string::npos) {
        cout << "Nimessa ei kirjainyhdistelmaa \"nen\"." << endl;
    } else {
        cout << "Yhdistelma \"nen\" loytyi kohdasta " << apu << endl;
    }
}

find palauttaa arvon string::npos, jos etsittyä merkkijonoa ei löydy. string::size_type on indeksien ja merkkijonojen kokojen käsittelyyn tarkoitettu etumerkitön tyyppi. Älä sekoita sitä huolettomasti int-tyyppiin vertailuissa tai muunnoksissa.

Hyödyllisiä merkkijonometodeja

Pituus

length() palauttaa merkkijonon merkkien määrän:

string::size_type pituus = 0;
pituus = teksti.length();

Merkin lukeminen ja muuttaminen

at(indeksi) palauttaa indeksin kohdalla olevan merkin. Sijoituksen kohteena se korvaa kyseisen merkin. Virheellinen indeksi aiheuttaa poikkeuksen.

char merkki;
merkki = teksti.at(5);
teksti.at(2) = 'k';  // char-tyyppinen arvo

Merkkien poistaminen

erase(indeksi) poistaa merkkijonosta kaikki merkit annetusta indeksistä loppuun. erase(indeksi, pituus) poistaa enintään annetun määrän merkkejä kyseisestä kohdasta alkaen.

teksti.erase(4);
teksti.erase(2, 5);

Merkkijonon etsiminen

find(etsittävä) etsii ensimmäisen osuman merkkijonon alusta alkaen. find(etsittävä, indeksi) aloittaa annetusta indeksistä. Metodit palauttavat ensimmäisen osuman indeksin tai arvon string::npos, jos osumaa ei löydy.

string::size_type kohta = 0;
kohta = teksti.find("abc", 5);
if (kohta == string::npos) {
    // "abc" ei löytynyt indeksistä 5 eteenpäin
} else {
    // "abc" löytyi
}

rfind(etsittävä) etsii merkkijonon lopusta alkua kohti. rfind(etsittävä, indeksi) aloittaa käänteisen haun annetusta indeksistä.

Osamerkkijonon muodostaminen

substr(indeksi) palauttaa osamerkkijonon annetusta indeksistä loppuun. substr(indeksi, pituus) palauttaa kyseisestä kohdasta alkaen enintään annetun määrän merkkejä.

string teksti = "abcdefg";
string tulos;
tulos = teksti.substr(3);     // "defg"
tulos = teksti.substr(4, 2);  // "ef"

Tekstin lisääminen ja korvaaminen

insert(indeksi, lisäys) lisää tekstin ennen annettua kohtaa. replace(indeksi, pituus, korvaava) korvaa annetusta kohdasta alkaen enintään pituuden verran merkkejä.

string teksti = "abcd";
teksti.insert(2, "xy");  // "abxycd"

string toinen = "ABCDEF";
toinen.replace(1, 3, "xy");  // "AxyEF"

Merkkijono-operaattorit

Merkkijonoja voi vertailla operaattoreilla ==, !=, <, >, <= ja >=. Suurempi- ja pienempi kuin -operaattorit vertailevat leksikaalista järjestystä, joka muistuttaa aakkosjärjestystä.

+-operaattori liittää kaksi merkkijonoa yhteen:

string testi1 = "Qt";
string testi2 = "Creator";
string tulos = testi1 + " " + testi2;  // "Qt Creator"

+=-operaattori liittää merkkijonon tai yksittäisen char-merkin merkkijonon loppuun:

string tulos = "Qt";
tulos += ' ';        // "Qt "
tulos += "Creator";  // "Qt Creator"

Merkkijonoihin liittyviä funktioita

getline(virta, rivi) lukee yhden tekstirivin tietovirrasta, kuten näppäimistöltä cin-virrasta, ja tallentaa sen rivi-muuttujaan.

stoi(teksti) muuntaa tekstin kokonaisluvuksi. stod(teksti) muuntaa tekstin liukuluvuksi.

string numeerinen_teksti = "123";
int luku = stoi(numeerinen_teksti);  // 123

string desimaaliteksti = "123.456";
double arvo = stod(desimaaliteksti);  // 123.456

stoi ja stod voivat hyväksyä kelvollisen lukualun ja ohittaa perässä tulevat merkit. Esimerkiksi stoi("123abc") voi palauttaa arvon 123. Tarkista koko syöte, jos myös lopun kelvollisuus on tärkeää.