Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Ääkköset ja ikkuna (C++)

Sivun loppuun

Vihru [27.01.2006 16:03:06]

#

Latasin Dev-C++:n uusimman version.
Ääkköset ei toimi, miten ne voi saada toimimaan?
Kiitos! Entäs kun se ikkuna sulkeutuu heti kun se on suoritettu?

TeeVee [27.01.2006 16:15:04]

#

Vihru kirjoitti:

Latasin Dev-C++:n uusimman version.
Ääkköset ei toimi, miten ne voi saada toimimaan?
Kiitos! Entäs kun se ikkuna sulkeutuu heti kun se on suoritettu?

Ikkuna sulkeutuu, koska ohjelmasi on tod näk helloworld ja se on tarkoitettu ajettavaksi komentoriviltä.

Vihru [27.01.2006 16:21:16]

#

No juu, komentokehotteella saa sen suoritettua kyllä ilman että se ei sulkeudu, eikö sitä saa millään koodin pätkällä?
Esim. pause tai getchar?

Ja nuo ääkköset enemmän hämää..
Kiitos!

Jaska [27.01.2006 16:21:24]

#

Tietysti hakukoneitakin saa käyttää. Ääkkösongelman ratkaisu voi löytyä
Sfnetin keskusteluryhmästä. En tiedä, kun en kyseistä kääntäjää käytä.

Vihru [27.01.2006 16:33:18]

#

kiitos linkistä, muita neuvoja? =)

Baglair [27.01.2006 16:41:18]

#

Vai ei ääkköset toimi? No annappa esimerkki missä ne ei toimi ni katotaan. Niitten kanssa kyllä tulee aina vähän ongelmia, koska ne eivät käsittääkseni ole vain yhtä tavua vaan kaksi.

Vihru [27.01.2006 16:50:19]

#

cout << "Kerrohan minulle ik\x84si?\n";
cin >> ika;


Nyt toimii ääkköset :) kun kirjottaa noin.

Entäs miten saisin sillain, että kun painaa entteriä, se vasta jatkaa eteepäin?
getchar? :)

Baglair [27.01.2006 16:56:46]

#

no sillä nimenomaan vaikka. Mutta se on vähä sellanen "purkkaratkasu".

Jonkinmmoinen C esimerkki:

#include <stdio.h>

int main(void)     {
     ...
     getchar();
}

Vihru [27.01.2006 16:58:34]

#

cout << "Kerrohan minulle nimesi?\n";
   cin >> nimi;

Miten saan rajoitettua, kuinka pitkän nimen voi kirjoittaa?

string nimi;

ja string kirjasto on sisällutetty tuohon..?

Baglair [27.01.2006 17:08:31]

#

Mikset tee tuota taulukolla? Ei siihen mitään stringejä tarvita.

Siis

char nimi[KOKO];

Vihru [27.01.2006 17:12:11]

#

kiitos, mutta se menee ohjelman lopppuun jos pistän pitkän nimen, mistäköhän se voisi johtua? :)

Baglair [27.01.2006 17:16:40]

#

No siitä, että ohjelmasi on virheellinen. Olisi hyvä jos voisit laittaa lähdekoodin näkyville.

Vihru [27.01.2006 17:19:56]

#

Olen vasta alottelija, ettei tuossa minun ohjelmassani mitään "järkeä" ole, kunhan harjoittelen ja opettelen.

#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{

char nimi [20];
   int ika;

   cout << "Tervetuloa minun ensimm\x84iseen ohjelmaan! Paina ENTER jatkaaksesi.\n";
   getchar();

   cout << "Kerrohan minulle nimesi?\n";
   cin >> nimi;

   cout << "Kerrohan minulle ik\x84si?\n";
   cin >> ika;


   cout << "\n\nTerve " << nimi << ", olet " << ika << "-vuotias!\n\n";
   return 0;
}

Baglair [27.01.2006 17:29:16]

#

Katso ohjeista kooditagit; selkeyttää koodia.

Tosiaan sanoin jo etten ole C++ taitaja mutta voisit korvata tuon nimen kyselyn seuraavalla koodilla ja lisätä alkuun muuttujan x:

int main(void)   {
   int x;
   ...
   cout << "Kerrohan minulle ik\x84si?\n";
   for(x=0;x<=20;++x)   {
      nimi[x] = getchar();
      if(nimi[x] == '\n')   {
         nimi[x] = '\0';
         break;
      }
   }
   ...
}

Vihru [27.01.2006 18:48:50]

#

Minusta tuo vaikuttaa vielä sekavammalta :)

tn [27.01.2006 19:41:50]

#

1. Ohjelmasi tilttaa koska kirjoitat kirjoitat pidemmän tekstin, kuin mitä kohdetaulukko antaa myöten. Tuossa tapauksessa jos kirjoitat yli 20 merkkiä pitkän nimen, niin se vuotaa taulukon yli jonkin muun (ehkä tärkeän) datan päälle. Tästä syystä suosittelenkin käyttämään stringiä, jolla ei moista ongelmaa ole. Etenkään se, kumpaa käyttää ei itsessään rajoita mitenkään syötettävän merkkijonon pituutta.

2. Jos haluat, että ohjelma rajoittaa syötteen pituutta jo syöttövaiheessa, joudut luultavasti koodaamaan itse tätä varten funktion. Standardi merkkijononlukemisfunktioilla kyseinen homma ei nimittäin onnistu. Joudut siis lukemaan tekstiä merkki kerrallaan vähän tuohon tyyliin, miten Baglair tuossa ylempänä näytti.

3. Voit myös tehdä niin, että annat käyttäjän syöttää miten pitkän merkkijonon hyvänsä jonka vasta lopuksi syötteen jälkeen lyhennät oikean mittaiseksi. Tämä onnistuu paljon helpommin.

Metabolix [27.01.2006 20:33:56]

#

Baglair: Neuvosi ovat täyttä purkkaa. Ei millään pahalla, mutta kuitenkin. (Ja kaikkihan tietävät, että kun char-tauluun lukeva ohjelma kaatuu, niin silloin on menty char-taulun yli :)

http://www.cplusplus.com/ref/iostream/istream/getline.html

char nimi[20];
cout << "Anna nimesi: ";
cin.getline(nimi, 20); // Max. 20 merkkiä

Kannattaa ihan C++:n dokumentaatiosta katsoa, mitä cin-oliosta (istream-tyypistä) kerrotaan.

Juice [27.01.2006 21:20:35]

#

Kyllä se string-luokka on vaan kätsympi ;)

Metabolix [27.01.2006 21:35:03]

#

Tietenkin string-luokalla voi tehdä näin:

cin >> str;
if (str.length() > 20)
  str.resize(20);

En tosiaan näe mitään syytä katkoa merkkijonoa väkisin tuosta kohti, ellei tosiaan ole tilanpuute edessä.

koo [27.01.2006 22:55:46]

#

Ääkköset eivät ehkä toimi siksi, että Windows käyttää luontaisesti eri merkistöä kuin sen Dos-ikkuna. Kun koodi kirjoitetaan jollakin Windows-editorilla, ääkköset tulostuvat muina merkkeinä, kun ohjelmaa ajellaan komentoikkunassa. Tai sitten ei.

Merkkijonoja ei lueta ikinä koskaan merkkitaulukoihin, ellei samalla ehdottomasti anneta taulukon kokoa. C-ohjelmat ovat kautta aikojen kaatuilleet tai tehneet muita tyhmyyksiä, kun taulukot ovat vuotaneet yli.

C++:ssa kannattaa muutoinkin käyttää string-luokkaa. Se ei kuitenkaan itsessään ratkaise tätä ylivuoto-ongelmaa, sillä on loppujen lopuksi aika sama, kaatuuko ohjelma ylivuotoon vai siihen, että joku syöttääkin teratavun mittaisen merkkijonon. Maksimipituus ja ylipäätään virheellinen syöte pitää kuitenkin hanskata jotenkin.

Pituutta voi rajoitella setw-manipulaattorilla:

#include <iomanip>
#include <iostream>
#include <limits>
#include <string>

int main()
{
        std::cout << "kerrohan nimesi: ";
        std::string nimi;
        if (std::cin >> std::setw(10) >> nimi)
                std::cout << "siis \"" << nimi << "\"\n";
        else
        {
                std::clog << "nimen lukeminen ei onnistu\n";
                std::cin.clear();
        }
        std::cin.ignore(std::numeric_limits<int>::max(), '\n');

        std::cout << "ja salasanasi: ";
        std::string salasana;
        if (std::cin >> std::setw(10) >> salasana)
                std::cout << "ahaa \"" << salasana << "\"\n";
        else
        {
                std::clog << "salasanan lukeminen ei onnistu\n";
                std::cin.clear();
        }
        std::cin.ignore(std::numeric_limits<int>::max(), '\n');

        std::cout << "entä ikäsi: ";
        int ika;
        if (std::cin >> ika)
                std::cout << "vaude, " << ika << " vuotta\n";
        else
        {
                std::clog << "iän lukeminen ei onnistu\n";
                std::cin.clear();
        }
        std::cin.ignore(std::numeric_limits<int>::max(), '\n');

        // lopetetaan vasta enterin jälkeen
        std::cin.ignore(std::numeric_limits<int>::max(), '\n');
}

Tuossa on vähän vihjettä myös siihen, miten virheellistä syötettä voi yrittää hoidella.

Stringiin luku tyssää ensimmäiseen whitespaceen, joten jos antaa nimeksi Matti Meikäläinen, tulos ei ehkä vastaa odotuksia. Tätäkin voi toki asetella manipulaattorilla.


Sivun alkuun

Vastaus

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

Tietoa sivustosta