String index out of range-virheilmo

millä ilveellä pystyisin tarkastamaan merkkijonon pituuden, ilman, että ohjelma kaatuu. Tarkoituksena on syöttää neljän merkin pituinen String ja tehdä tarkistus, jotta ohjelma voisi edetä. Olen kirjoittanut

if (mjono.length() < 4)
System.out.println ("liian vähän merkkejä)

ja ohjelma kyllä ilmoittaa, merkkien vähyyden, mutta katuu siihen ja ilmoittaa, että

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.charAt(String.java:558)
Press any key to continue...

Epätoivo alkaa olla lamannuttava ja kiire olisi päästä eteenpäin
101352
Äänestä

Muut lukivat myös

Vastaukset 10

Vanhimmat

Näinköhän yrität tuon jälkeen, if:n else haarassa, ottaa mjono:ssa indeksillä 4 olevaa merkkiä johonkin käyttöön? Stringin indeksit lähtee nollasta, eli neljän pituisessa merkkijonossa indeksit ovat 0-3.

char merkki = mjono.charAt(3);

Äänestä
  • Tarkoituksena olisi vain saada aikaan ilmoitus käyttäjälle, että merkkejä on syötetty liian vähän ja kehoitaa yrittämään uudestaan.

    else if (mjono.length() > 4)
    System.out.println("liikaa merkkejä")

    menee läpi ihan ongelmitta. Käsittääkseni mjono.length() kertoo merkkijonon merkkien määrän, eikö?

    Äänestä

  • koodi-täti kirjoitti:

    Tarkoituksena olisi vain saada aikaan ilmoitus käyttäjälle, että merkkejä on syötetty liian vähän ja kehoitaa yrittämään uudestaan.

    else if (mjono.length() > 4)
    System.out.println("liikaa merkkejä")

    menee läpi ihan ongelmitta. Käsittääkseni mjono.length() kertoo merkkijonon merkkien määrän, eikö?

    Ei ohjelmasi siihen tarkastukseen kaadu vaan riville 558, kuten se virhe kertoi.

    Äänestä

  • Joopa joo kirjoitti:

    Ei ohjelmasi siihen tarkastukseen kaadu vaan riville 558, kuten se virhe kertoi.

    mille ihmeen riville 558, kun koko ohjelmanpätkässä tähän mennessä on yhteensä vain 143 riviä

    Äänestä

  • koodi-täti kirjoitti:

    Tarkoituksena olisi vain saada aikaan ilmoitus käyttäjälle, että merkkejä on syötetty liian vähän ja kehoitaa yrittämään uudestaan.

    else if (mjono.length() > 4)
    System.out.println("liikaa merkkejä")

    menee läpi ihan ongelmitta. Käsittääkseni mjono.length() kertoo merkkijonon merkkien määrän, eikö?

    Jos pistät vähän enemmän niitä koodirivejä näkyville niin voisi sanoa tarkemmin. En jaksa uskoa että suoritus kaatuisi tuohon mjono.length()-metodiin.

    Ihan oikeassa olet kuitenkin siitä mitä tuo length tekee.

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#length()

    Äänestä

  • .... kirjoitti:

    Jos pistät vähän enemmän niitä koodirivejä näkyville niin voisi sanoa tarkemmin. En jaksa uskoa että suoritus kaatuisi tuohon mjono.length()-metodiin.

    Ihan oikeassa olet kuitenkin siitä mitä tuo length tekee.

    http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#length()

    No. Tarkoituksena on tehdä Mastermind-peli, joka arpoo ensin randomina 4 kirjainta ja käyttäjän hommana on yrittää arvata se. Tein (tai yritin tehdä) metodin, joka tarkastaaa ensin pelaajan arvauksen pituuden ja ilmoittaa, jos se on joko liian lyhyt tai liian pitkä.

    Metodi kokonaisuudessaan on

    static void tarkistaPituus(String mjono) {
    boolean ok = false;

    if (mjono.length() == 4) {
    ok = true;
    }
    if (mjono.length() < 4) {
    System.out.println("Et antanut tarpeeksi kirjaimia!");
    }
    if (mjono.length() > 4){
    System.out.println("Annoit liian monta kirjainta!");
    }
    }

    Käyttäjän arvaus on mainissa määritelty vain String arvaus; ja metodikutsuna tarkistaPituus(arvaus);. Jos tarvitsee vielä lisäselvennystä, niin pistän vaikka koko roskan tänne.

    Äänestä

  • koodi-täti kirjoitti:

    mille ihmeen riville 558, kun koko ohjelmanpätkässä tähän mennessä on yhteensä vain 143 riviä

    Se olikin näköjään "String.java":n rivi, (olisit laittanut koko virheilmoituksen). Siitä virheilmoituksessa näkyy kyllä tarkasti, millä ohjelman rivillä se virhe tapahtuu. Ja laita se koko koodi, jos haluat, että joku pystyy auttamaan.

    Mikä ihmeen se turha ok muuttuja on tarkistaPituus metodissa?

    Äänestä

  • koodi-täti kirjoitti:

    No. Tarkoituksena on tehdä Mastermind-peli, joka arpoo ensin randomina 4 kirjainta ja käyttäjän hommana on yrittää arvata se. Tein (tai yritin tehdä) metodin, joka tarkastaaa ensin pelaajan arvauksen pituuden ja ilmoittaa, jos se on joko liian lyhyt tai liian pitkä.

    Metodi kokonaisuudessaan on

    static void tarkistaPituus(String mjono) {
    boolean ok = false;

    if (mjono.length() == 4) {
    ok = true;
    }
    if (mjono.length() < 4) {
    System.out.println("Et antanut tarpeeksi kirjaimia!");
    }
    if (mjono.length() > 4){
    System.out.println("Annoit liian monta kirjainta!");
    }
    }

    Käyttäjän arvaus on mainissa määritelty vain String arvaus; ja metodikutsuna tarkistaPituus(arvaus);. Jos tarvitsee vielä lisäselvennystä, niin pistän vaikka koko roskan tänne.

    Tuo boolean ok siis kertoo ohjelmalle onko merkkijono sopivan mittainen ja voidaanko jatkaa eteenpäin? Sitä vaan ei tuossa tapauksessa palauteta mihinkään vaan se jää tuon metodin sisäiseksi muuttujaksi.

    Tuon metodin määrittely pitäisi olla jotain tähän suuntaan
    static boolean tarkistaPituus(String mjono)
    ja metodin lopussa pitäisi olla rivi
    return ok;

    Pääohjelmassa pitäisi olla jotain tähän suutaan

    if(tarkistaPituus(mjono)){
    teeJotainMerkkijonolle...
    }
    else{
    teeJotainMuuta
    }


    Muuten tuo merkkijonon pituuden tarkistaminen on ihan oikein, mutta tarkistuksen arvoa ei jatkossa käytetä mihinkään.

    Yleisesti koodaillessa kannattanee pistää koodin väliin System.out.println-rivejä, joilla voi selvittää mihin asti koodi etenee ja missä virhe oikeasti tulee. Tuossa tarkistaPituus-metodissa ei ole mitään josta tuo alkuperäinen poikkeus tulisi.

    Äänestä

  • ..... kirjoitti:

    Tuo boolean ok siis kertoo ohjelmalle onko merkkijono sopivan mittainen ja voidaanko jatkaa eteenpäin? Sitä vaan ei tuossa tapauksessa palauteta mihinkään vaan se jää tuon metodin sisäiseksi muuttujaksi.

    Tuon metodin määrittely pitäisi olla jotain tähän suuntaan
    static boolean tarkistaPituus(String mjono)
    ja metodin lopussa pitäisi olla rivi
    return ok;

    Pääohjelmassa pitäisi olla jotain tähän suutaan

    if(tarkistaPituus(mjono)){
    teeJotainMerkkijonolle...
    }
    else{
    teeJotainMuuta
    }


    Muuten tuo merkkijonon pituuden tarkistaminen on ihan oikein, mutta tarkistuksen arvoa ei jatkossa käytetä mihinkään.

    Yleisesti koodaillessa kannattanee pistää koodin väliin System.out.println-rivejä, joilla voi selvittää mihin asti koodi etenee ja missä virhe oikeasti tulee. Tuossa tarkistaPituus-metodissa ei ole mitään josta tuo alkuperäinen poikkeus tulisi.

    edellisessä viestissä tulikin jo esille, että miksi homma ei nyt toimi. Tämä tarkistava metodi tarkistaa merkkijonon pituuden oikein, mutta arvoa ei palauteta mihinkään.

    Siitä johtuen mainissa rullataan iloisesti sellaiseen osaan, jossa merkkijonoa aletaan käsitellä. Virheilmoitus tulee siis siitä, kun yritetään merkkijonosta ottaa charAt()-metodilla tietyllä indeksillä jotain merkkiä ja merkkijono on null tai liian lyhyt.

    Muutenki kannattaa käyttää jotain debuggaustyyliä liitettynä try&catchiin, jolla saadaan virheet kiinni.

    Luokan alkuun teet vaikka muuttujan private static boolean DEBUG = true;

    Tällä muuttujalla voit sitten säätää, että tuleeko ruudulle debug-viestejä vai ei

    Sitten oman metodin, joka tulostelee debuggausviestejä System.outtiin

    private debug(String message)
    {
    if(DEBUG)
    {
    System.out.println(message);
    }
    }

    Sitten vain käytät tätä metodeissasi

    public static boolean tarkistaPituus(String mjono)
    {
    debug("Metodi tarkistaPituus alkaa...");
    boolean ok = false;

    try
    {
    if(mjono != null && mjono.length() > 3)
    {
    ok = true;
    }
    }
    catch (Exception e)
    {
    debug("VIRHE metodissa tarkistaPituus!");
    e.printStackTrace();
    }
    finally
    {
    debug("Metodi tarkistaPituus loppui: palautusarvo: " ok);
    return ok;
    }
    }


    Kun ohjelma toimii täysin, niin sitten muutat vain
    private static boolean DEBUG = false;

    ja sovellusta käyttäessä ei tule turhaa roskaa näytölle

    Äänestä

koodisi näytää jokseenkin tältä:

if (mjono.length() < 4)
System.out.println ("liian vähän merkkejä)

char c = mjono.charAt(3);

Eli toteat että liian vähän merkkejä, mutta kuitenkin yrität lukea siitä.

ratkaisu:

if (mjono.length() < 4)
{
System.out.println ("liian vähän merkkejä)
}
else
{
char c = mjono.charAt(3);
// ... jotain
}

tai

if (mjono.length() < 4)
{
System.out.println ("liian vähän merkkejä)
return; // pelleily lopuu tähän ;)
}

char c = mjono.charAt(3);

Äänestä

Kommentoi aloitusta


koodi-täti kirjoitti:

millä ilveellä pystyisin tarkastamaan merkkijonon pituuden, ilman, että ohjelma kaatuu. Tarkoituksena on syöttää neljän merkin pituinen String ja tehdä tarkistus, jotta ohjelma voisi edetä. Olen kirjoittanut

if (mjono.length() < 4)
System.out.println ("liian vähän merkkejä)

ja ohjelma kyllä ilmoittaa, merkkien vähyyden, mutta katuu siihen ja ilmoittaa, että

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.charAt(String.java:558)
Press any key to continue...

Epätoivo alkaa olla lamannuttava ja kiire olisi päästä eteenpäin

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu