Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Ääkköset ja Qt Creator (if-lauseessa)

vesikuusi [03.01.2012 18:51:38]

#

Ongelma: seuraava koodinpätkä aiheuttaa virheen.

if (input[i] == 'ä')
...
warning: multi-character character constant
warning: comparison is always false due to limited range of data type

Käytössä QtCreator (kääntäjä g++ 4.5.2)
Olen asettanut encodingin UTF-8:aan, mutten googlaamisesta huolimatta osaa hyödyntää sitäkään. Miten voin tarkistaa ääkköset merkkijonosta?

E: \x84 ja \x94 testattu, ei toimi ainakaan niillä encodingeilla mitä nyt on ollut käytössä. Mikähän on se asetus, jota Dev-C++ käyttää, jolla nuo toimii?

Metabolix [03.01.2012 19:08:54]

#

Mikä input on tyypiltään? Jos käytät char-tyyppiä (std::string-merkkijonoa), et voi tehdä noin. Yksi char käsittää yhden tavun, UTF-8-merkkijonossa yksi merkki voi olla useita tavuja pitkä. Jos käytät wchar_t-tyyppiä (std::wstring-merkkijonoa), merkin pitäisi olla L'ä'.

Mihin yleensäkään tarvitset tällaista ominaisuutta? Voi olla, että lähestyt asiaa aivan väärältä kannalta.

vesikuusi [03.01.2012 19:13:55]

#

Kyseessä on yksinkertainen chatbot, joka alussa siivoaa viestin erikoismerkeistä (jättää toki alkuperäisenkin version). Ääkköset pitäisi kuitenkin säästää.

input on std::string-tyyppinen.

tässä siivousfunktio:

Msg Bot::clean_msg(std::string input)
{
    PRINT2("CLEANING MESSAGE...");
    Msg clean;
    std::string cleanstr = "";

    for (unsigned i = 0; i <= input.length(); i++)
        if ((input[i] >= 'A' && input[i] <= 'z') ||
                input[i] == ' ' || (input[i] >= '0' &&
                input[i] <= '9') ||  input[i] == '<' ||
                input[i] == '>' || input[i] == '_')
            cleanstr.push_back(tolower(input[i]));

    clean = cleanstr;
    return clean;
}

Ja tuonne pitäisi lisätä ääkkösten tarkistus.

Ja kyllä, saattaa olla rumaa koodia, toivottavasti silmänne eivät kuitenkaan pala tästä :)

Triton [03.01.2012 22:09:36]

#

Mites, eikö tämän tyyppiset jutut kannattaisi ratkaista säännöllisillä lausekkeilla? C++:ssaan on olemassa omia kirjastoja niiden tekemiseen.
Esim. http://developer.qt.nokia.com/doc/qt-4.8/qregexp.html

Edit. Apua! Ota heti pois tuo PRINT2-makro tuolta metodin sisältä :D

vesikuusi [05.01.2012 15:33:22]

#

Metabolix kirjoitti:

--merkin pitäisi olla L'ä'.

Kaiken järjen mukaan kyllä, mutta silti seuraava koodinpätkä ei toimi, niin kuin olettaisi:

wchar_t wchar;

for (unsigned i = 0; i < str.length(); i++)
    {
        wchar = str[i];

        if (wchar == L'ä')
            str.replace(i, 2, "&auml; ");
...

Ohjelma ei tunnista ä-kirjainta. Missä menee vikaan?

Edit. str on siis std::string-tyyppinen. Sen pitäisi varmaan olla std::wstring-tyyppiä? Pitänee ensi kerralla suunnitella projekti vähän paremmin :D

Edit2. seuraavakaan viritelmä ei printtaa "Match!":

std::wstring string2wstring(std::string str)
{
    std::wstring wstr(str.length(),L' ');
    std::copy(str.begin(),str.end(),wstr.begin());
    return wstr;
}


int main()
{
    std::string str ("Miäs");
    std::wstring wstr (string2wstring(str));

    for (unsigned i = 0; i < wstr.length(); i++)
        if (wstr[i] == L'ä')
            std::cout << "Match!";

    return 0;
}

Mutta "Match!" tulee, jos wstr:n alustaa näin:

std::wstring wstr (L"Miäs");

Mitenhän saisin muunnettua stringin wstringiksi niin, että ne ääkköset sun muut löytyvät sieltä vertailussa?

Metabolix [05.01.2012 16:05:28]

#

Minusta se toimii aivan täsmälleen oletusten mukaan: väärin. Viitsisitkö nyt tajuta edes sen perusasian, että UTF-8-enkoodattu "ä" on sama kuin "\xc3\xa4"? Et siis voi mitenkään käsitellä sitä tavu kerrallaan, koska saat silloin vain tavun '\xc3' tai '\xa4' eikä kummastakaan voi yksinään tunnistaa ä-kirjainta. Kaikki viritelmäsi tekevät aivan täsmälleen saman virheen.

Wikipedian UTF-8-artikkelissa on selvä kuvaus merkkien koodauksesta. Voit tehdä sen pohjalta funktion, joka erottelee yksittäiset UTF-8-merkit, jotka siis ovat usean tavun mittaisia. Voit siis sijoittaa yhden merkin yhteen std::string-muuttujaan ja tehdä vertailun normaaliin tapaan merkkijonoilla: merkki == "ä". Halutessasi voit muuttaa yksittäiset UTF-8-merkit (tavujonot) vielä wchar_t-merkeiksi eli yksittäisiksi Unicode-arvoiksi.

Lyhyesti sanottuna kelvollinen UTF-8-merkki on tavu, jossa ylin bitti on nolla ((x & 0x80) == 0), tai tavujono, jonka ensimmäisen tavun ylimmät bitit ovat 11 ((x & 0xc0) == 0xc0) ja jossa on yhtä monta tavua kuin ykkösbittiä ensimmäisen tavun alussa.

vesikuusi [05.01.2012 16:13:47]

#

Metabolix kirjoitti:

Viitsisitkö nyt tajuta edes sen perusasian, että UTF-8-enkoodattu "ä" on sama kuin "\xc3\xa4"?

Viitsisin. Kiitos.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta