No hej.. miten/millä funktiolla saan tarkistettua sisältääkö joku lause vaik sanan "ohjelmointi" (kirjainkoolla ei pitäs olla väliä ja se saa esiintyä vaik keskellä jotain toista sanaa)?
Eli siis se toimis jotenki tähän tapaan: "Ohjelmointiputka: Keskustelu: C / C++ ja Delphi / Pascal - Opera" -> return KyllaLoytyi;
"C++ - Wikipedia - Opera" -> return EiLoytynyt;
eli siis toi lainausmerkeissä oleva on se tarkistettava jutska ja ylemmästä löytyy sana ohjelmointi (OHJELMOINTIputka).
Sitä Googlea kannattaa käyttää...
No jokatapauksessa esim. http://www.cppreference.com saattaa auttaa jatkossa.
string mjono("Ohjelmointiputka: Keskustelu: C / C++ ja Delphi / Pascal - Opera"); string::size_type loc = mjono.find( "Opera", 0 ); if (loc != string::npos) { cout << "Löyty" << endl; } else { cout << "Ei löytyny" << endl; }
Legu kirjoitti:
Sitä Googlea kannattaa käyttää...
No jokatapauksessa esim. http://www.cppreference.com saattaa auttaa jatkossa.string mjono("Ohjelmointiputka: Keskustelu: C / C++ ja Delphi / Pascal - Opera"); string::size_type loc = mjono.find( "Opera", 0 ); if (loc != string::npos) { cout << "Löyty" << endl; } else { cout << "Ei löytyny" << endl; }
No nyt se valittaa että "`find' is not a type" ja "request for member of non-aggregate type before '(' token"
Onko #include <string> mukana?
Huomaa myös ettö string sijaitsee std-nimiavaruudessa.
Mazzimo kirjoitti:
Onko #include <string> mukana?
Huomaa myös ettö string sijaitsee std-nimiavaruudessa.
Kyllä oon mielestäni ottanu molemmat asiat huomioon.
#include <string> using namespace std;
Tämähän riittää vai?
Tämä kääntyi ja toimi minulla.
#include <iostream> #include <string> using namespace std; int main() { string mjono("Ohjelmointiputka: ... Pascal - Opera"); string::size_type loc = mjono.find( "Opera", 0 ); if (loc != string::npos) { cout << "Löyty" << endl; } else { cout << "Ei löytyny" << endl; } }
Sisennys ehkä vähän pielessä. Anteeksi, jos on. Lyhensin myös merkkijonoa, mutta se ei vaikuta esimerkkiin.
Ja jos haluaa, että kirjainkoolla ei ole väliä, pitää hakusana ja teksti muuttaa vaikkapa pieniksi kirjaimiksi. Onnistuu seuraavanlaisella funktiolla:
#include <cctype> #include <string> #include <iostream> #include <cstdlib> using namespace std; string pieneksi(string sana) { for ( unsigned int i = 0 ; i < sana.length() ; ++i ) { sana.at(i) = tolower(sana.at(i)); // Skandeille muunnos tod.näk. tehtävä manuaalisesti } return sana; } // Ja näin se toimii: int main() { string teksti = "KiSSa KoIIRAIAIAI kel ELELE!!!"; string pienena = pieneksi(teksti); cout << pienena; // tulostuu "kissa koiiraiaiai kel elele!!!" return EXIT_SUCCESS; }
TsaTsaTsaa kirjoitti:
Skandeille muunnos tod.näk. tehtävä manuaalisesti
Muunnoshan riippuu käytettävästä merkistöstä sekä kielestä/maasta jossa muunnosta tehdään. Aina pienten/isojen kirjainten 1:1-muunnosta ei edes voi tehdä. Lähimmäksi kuitenkin voisi päästä, kunhan vain antaa tuolle tolower
-funktiolle parametriksi olosuhteita kuvaavan locale
:n. Oletuslokaali "C" kun passaa lähinnä vain jenkeille, jotka eivät ääkkösiä yms. oikein tajua. Mutta locale
-otuksen kautta joka tapauksessa pääsee käsiksi kaikenlaisiin muihinkin vehkeisiin (esim. collate
), joilla voi käsitellä tietojen esitystapaa.
HWND ikkuna; char* texti; int length; while(1) { ikkuna = GetForegroundWindow(); length = GetWindowTextLength(ikkuna); GetWindowText(ikkuna, texti, length); string::size_type loc = texti.find("ohjelmointi", 0); if (loc != string::npos) { DoSomething(); } }
Vaan tämäpä ei sitten toimikkaan :/. Mikäs avuksi? Onko jotain muuta keinoa kun toi .find
Muuta tuo char-taulukko stringiksi:
char* teksti = "Tekstiä tässä..."; string teksti2(teksti); teksti2.find(...); //jne
http://www.cppreference.com/cppstring/
string( const char* str );
Legu kirjoitti:
Muuta tuo char-taulukko stringiksi:
char* teksti = "Tekstiä tässä..."; string teksti2(teksti); teksti2.find(...); //jnehttp://www.cppreference.com/cppstring/
string_constructors.html: string( const char* str );
Kiitos, nyt toimii. Tavallaan.. sain käännettyä sen mutta heti ku käynnistän exen ni ohjelma kaatuu ja tulee windowsin virheraportti-viesti ruutuun :o. Mitä ihmettä?
Johtuu ihan siitä, että nyt GetWindowText kirjoittaa tuon tuloksen ties minne.
Muistia ei ole varattu tuolle tulokselle, eli näin pitäisi toimia:
HWND ikkuna; char* teksti; int length; string teksti2; ikkuna = GetForegroundWindow(); length = GetWindowTextLength(ikkuna) + 1; //nollatavulle + 1 teksti = new char[length]; GetWindowText(ikkuna, teksti, length); teksti2 = teksti; delete [] teksti;
Tuolla taitaisi toimia (tosin vain jos unicodea ei käytetä, "oikeasti" kuuluisi käyttää noita Microsoftin LPTSTR, TCHAR ym.)
Kannattaa opetella ihan jostain kirjasta/oppaasta nuo perusasiat (muistinhallinta, osoittimet, jne.)
Aloittelija3 kirjoitti:
Kiitos, nyt toimii. Tavallaan.. sain käännettyä sen mutta heti ku käynnistän exen ni ohjelma kaatuu ja tulee windowsin virheraportti-viesti ruutuun :o. Mitä ihmettä?
Vika voi olla tässä.
GetWindowText(ikkuna, texti, length);
texti-osoittimen pitää osoittaa muistialueeseen, jossa on length-muuttujan verran tilaa kirjoittaa tekstiä.
Jos määrittelet vaikkapa textin muodossa char texti[20];
, niin silloin Windows API-referenssin mukaan voit laittaa pituudeksi myös 20. Mikäli sieltä tulee enemmän tekstiä, se katkeaa 19:ään merkkiin, koska myös loppumerkille pitää jäädä tila.
Sinun vastuullasi on varata tarpeeksi tilaa saadulle tekstille ja kertoa funktiolle length-parametrilla, mikä on sen tilan maksimikoko.
http://msdn2.microsoft.com/en-us/library/ms633520.aspx
Jos tämä on hepreaa, opettele pointterit ja muistinvaraus alusta asti. Ei se ole vaikeaa, mutta liian pitkä aihe tässä käytäväksi.
Tosin voi se ohjelma kaatua muistakin syistä. Auttaisi varmaan, jos voisit antaa kokonaisen ohjelman, josta olet karsinut kaiken turhan pois.
Kiitos tuhannesti Kopeekka ja muut! Sain toimimaan :)
Legu kirjoitti:
Kannattaa opetella ihan jostain kirjasta/oppaasta nuo perusasiat (muistinhallinta, osoittimet, jne.)
Esimerkki on ihan täyttä asiaa, mutta yksi perusasia unohtui. Kymmenen pointsia ja virtuaalinen virvoitusjuoma sille, joka äkkää, mitä tässä tapahtuu ratkaisevasti eri tavalla, vaikka periaatteessa tehdään ihan samat asiat:
HWND ikkuna = GetForegroundWindow(); int const length = GetWindowTextLength(ikkuna) + 1; vector<char> teksti(length); GetWindowText(ikkuna, &teksti[0], length); string teksti2(&teksti[0]);
(Funktioiden paluuarvot pitäisi tarkastaa ja suosia Windowsin TCHAR-määritystä, mutta ei nyt välitetä näistä.)
string str; HWND ikkuna = GetForegroundWindow(); int const length = GetWindowTextLength(ikkuna) + 1; str.resize(length); GetWindowText(ikkuna, &str[0], length); // cout << str << endl; tai vastaavaa
Eikös tällainenkin toteutus ole mahdollinen?
Standardin mukaan ei (vielä) ole. Ja vaikka olisikin, stringin pituutta pitäisi lopuksi vielä säätää, jotta '\0' tulisi oikein käsiteltyä.
Mutta se varsinainen pointti oli siinä, että se aiempi esimerkkisi voi vuotaa muistia, mutta viilaamani versio ei.
koo kirjoitti:
Esimerkki on ihan täyttä asiaa, mutta yksi perusasia unohtui. Kymmenen pointsia ja virtuaalinen virvoitusjuoma sille, joka äkkää, mitä tässä tapahtuu ratkaisevasti eri tavalla, vaikka periaatteessa tehdään ihan samat asiat:
HWND ikkuna = GetForegroundWindow(); int const length = GetWindowTextLength(ikkuna) + 1; vector<char> teksti(length); GetWindowText(ikkuna, &teksti[0], length); string teksti2(&teksti[0]);
Viittaus oli tähän koodiin.
Legu kirjoitti:
HWND ikkuna; char* teksti; int length; string teksti2; ikkuna = GetForegroundWindow(); length = GetWindowTextLength(ikkuna) + 1; //nollatavulle + 1 teksti = new char[length]; GetWindowText(ikkuna, teksti, length); teksti2 = teksti; delete [] teksti;
Saako pelata vielä jälkikäteen?
Kohdasta teksti2 = teksti
voi seurata std::bad_alloc
-poikkeus, jos stringiä luodessa sille ei voida varata tarpeeksi muistia. Sen jälkeen delete []
jää suorittamatta, mikä aiheuttaa mainitun muistivuodon.
Onko joku muu mahdollisuus jättää deletointi suorittamatta?
Koon versiossa vektori siivoa itse jälkensä, olipa tilanne poikkeuksellinen tai ei.
Juuri näin se menee. Exception safety on tärkeä juttu C++:n kanssa. Ja kyllä se pitää ottaa huomioon muissakin kielissä, sillä ei esimerkiksi garbage collection ihan kaikkia juttuja paranna sekään.
Aihe on jo aika vanha, joten et voi enää vastata siihen.