Hello, I have written a program for an assignment and all was working well, I tested everything and all that was left was to put in a few error-messages. Then, I changed the format from ISO to utf-8 and when I tried to run it again it suddenly stops at line 72-73. I have read through the code again and again but I can't see the error (of course, I'm no pro) and I have tried changing the format back to ISO and copying the code to create a new ISO file, but nothing works. If anyone could look over the code and see if they can find the error I'd be very happy:)

import java.util.Scanner;

class Bilregister{
  
  public static void main(String[] args) {
    
    int aldersforskjell = 0;
    
    System.out.println("Bil 1");
    Bil bilEn = beOmOpplysningerForBil();
    System.out.println("Bil 2");
    Bil bilTo = beOmOpplysningerForBil();
    
    if (bilEn.hentVekt() > bilTo.hentVekt()) {
        System.out.printf("Størst vekt: %1$s som veier %2$s kilo.\n", bilEn.hentBilMerke(), bilEn.hentVekt());
    } else if (bilEn.hentVekt() < bilTo.hentVekt()) {
        System.out.printf("Størst vekt: %1$s som veier %2$s kilo.\n", bilTo.hentBilMerke(), bilTo.hentVekt());
    } else {
        System.out.printf("Størst vekt: Begge bilene veier %1$s kilo.\n", bilEn.hentVekt());
    }
    
    if (bilEn.hentArsmodell() > bilTo.hentArsmodell()) {
        aldersforskjell = bilEn.hentArsmodell() - bilTo.hentArsmodell();    
    } else {
        aldersforskjell = bilTo.hentArsmodell() - bilEn.hentArsmodell();
    }
    System.out.printf("Aldersforskjell mellom bilene er %s år.", aldersforskjell);
  }
  
  static boolean kjennetegnErGyldig(String kjennetegn) {
    if (kjennetegn.length() != 7) {
      System.out.println("Kjennetegn skal være 7 tegn");
      return false;
    }      
    char kjennetegnBokstav1 = kjennetegn.charAt(0);
    char kjennetegnBokstav2 = kjennetegn.charAt(1);
    if (! (kjennetegnBokstav1 >= 'A' && kjennetegnBokstav1 <= 'Z' && kjennetegnBokstav2 >= 'A' && kjennetegnBokstav2 <= 'Z') ) {
      System.out.println("De første to tegnene i kjennetegn må være store bokstaver");
      return false;
    }
    if (! (kjennetegn.charAt(2) >= '1' && kjennetegn.charAt(2) <= '9') )  {
      System.out.println("Tegn 3 må være heltall mellom 1 og 9.");
      return false;
    }
    String famousFinalFour = kjennetegn.substring(3, kjennetegn.length());
    int tallPosisjon = 0;
    while (tallPosisjon <= famousFinalFour.length()) {
      if (! (famousFinalFour.charAt(tallPosisjon) >= '0' && famousFinalFour.charAt(tallPosisjon) <= '9') ) {
        System.out.println("De fire siste sifrene må være heltall mellom 0 og 9.");
        return false;   
      }  
    }
      return true;
  } 
  
  static Bil beOmOpplysningerForBil() {
    
    int arsmodell, vekt;
    String merke, kjennetegn;
    Scanner tastatur = new Scanner(System.in);
    
    System.out.println("Merke: ");
    merke = tastatur.next();
    
    System.out.println("Vekt: ");
    vekt = tastatur.nextInt();
    if (vekt < 300) {
      System.out.println("Feilmelding!");
    }
    
    do {
      System.out.println("Kjennetegn: ");
      kjennetegn = tastatur.next();
    }
    while(kjennetegnErGyldig(kjennetegn) == false);

    System.out.println("Årsmodell: ");
    arsmodell = tastatur.nextInt();
    
    Bil bilen = new Bil();
    bilen.settVekt(vekt);
    bilen.settBilMerke(merke);
    bilen.settArsmodell(arsmodell);
    bilen.settKjennetegn(kjennetegn);
    
    return bilen;  
  }
}

There's another class aswell. I don't know if it's needed to see, but in case

class Bil{
  
    String kjennetegn, merke;
    int arsmodell, vekt;

    /* Metoder som gir verdier til instansevariabler i klassen. */
    void settKjennetegn(String kt){
      kjennetegn=kt;
    }

    void settBilMerke(String m){
      merke=m;
    }

    void settArsmodell(int am){
      arsmodell=am;
    }

    void settVekt(int v){
      vekt=v;
    }

    /* Metoder som leser verdier til instansevariabler. */
    String hentKjennetegn(){
      return kjennetegn;
    }

    String hentBilMerke(){
      return merke;
    }

    int hentVekt(){
      return vekt;
    }

    int hentArsmodell(){
      return arsmodell;
    }
}

it suddenly stops at line 72-73

What does "suddenly stops" means?
Does the loop there never end?
If so, why isn't the variable being changed that allows the code out of the loop?
Add some debug printlns where the variable is supposed to be changed to determine why its value is not being changed.

Also the next() call may be blocking waiting for input. Try typing in something and pressing Enter.

Edited 5 Years Ago by NormR1: n/a

I mean that when I get to that point and I enter "kjennetegn" and then press enter, nothing more happens. It just stops. I tested it before I converted the format and it worked then. But after I changed the format (and I didn't do anything with the code), it just stops there. If the loop didn't end, it should give me the choice to enter "kjennetegn" again (right?), but it doesn't.

Type in some more and press Enter again.
Print out everything that is read in to see where it is being read.

What do you mean? I can't type in anything when it stops. When I put in something wrong for "kjennetegn (license plate number)", it works and i get an error and have to do it again. But when I enter a correct "kjennetegn", it stops. So it might be a loop-error afterall. When it should return true and move on, it doesn't, just stops and I have this windows-circle that goes round and round when it's working.

After that input you call the method at line 30 which will drop thru to the while at line 47. Which is a very interesting loop
while (tallPosisjon <= famousFinalFour.length())
neither tallPosisjon nor famousFinalFour seems to change inside the loop, which means if it executes right thru once it will loop infinitely - isn't that your symptom?

I can't type in anything when it stops

I'm not sure what you mean by "stops". One thing that will cause a program to stop is if it is waiting for a user to enter some data.
Try printing out the value of hasNext() before the call to next()

Add some printlns to kjennetegnErGyldig() to show the values.

Edited 5 Years Ago by NormR1: n/a

So you are saying that the method kjennetegnErGyldig correctly returns false when you enter wrong data but when you enter the right data the loop doesn't go to the System.out.println("Årsmodell: "); call ?

If yes then maybe the problem is with the kjennetegnErGyldig method. Try to add more prints at the beginning and the end. Specifically before you return true. Have you tested it? Since it is static you can call it alone from a main method and see if it returns true.

My guess is that when it enters the last loop it never exits:

while (tallPosisjon <= famousFinalFour.length()) {
  if (! (famousFinalFour.charAt(tallPosisjon) >= '0' &&      famousFinalFour.charAt(tallPosisjon) <= '9') ) {
  System.out.println("De fire siste sifrene må være heltall mellom 0 og 9.");
  return false;
}
}

Look at it. If it enters the loop you have no way to exit. The tallPosisjon will always be lower than the famousFinalFour.length. Shouldn't you be increasing the tallPosisjon with each loop, so eventually the tallPosisjon <= famousFinalFour.length will become false?

while (tallPosisjon < famousFinalFour.length()) {
  if (! (famousFinalFour.charAt(tallPosisjon) >= '0' &&      famousFinalFour.charAt(tallPosisjon) <= '9') ) {
  System.out.println("De fire siste sifrene må være heltall mellom 0 og 9.");
  return false;
}
tallPosisjon++;
}

Notice the the check should be: tallPosisjon < famousFinalFour.length without the equals. If it is equal the charAt will give you an ArrayIndexOutOfBounds Exception.
The tallPosisjon should be from 0 till famousFinalFour.length-1

@James: Yes, I saw that too and I tried to put an increment on tallPosisjon between line 51 and 52. But it didn't help, just gave me thios error-message:

"java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(Unknown Source)
at Bilregister.kjennetegnErGyldig(Bilregister.java:48)
at Bilregister.beOmOpplysningerForBil(Bilregister.java:76)
at Bilregister.main(Bilregister.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)"

@Norm: I'm a beginner with Java so not quite sure what you mean. I don't have a hasNext() or next() in my code? When it stops, I mean that it should move on to "arsmodell", but it doesn't. Nothing happens

@James: Yes, I saw that too and I tried to put an increment on tallPosisjon between line 51 and 52. But it didn't help, just gave me thios error-message:

"java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(Unknown Source)
at Bilregister.kjennetegnErGyldig(Bilregister.java:48)
at Bilregister.beOmOpplysningerForBil(Bilregister.java:76)
at Bilregister.main(Bilregister.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:271)"

@Norm: I'm a beginner with Java so not quite sure what you mean. I don't have a hasNext() or next() in my code? When it stops, I mean that it should move on to "arsmodell", but it doesn't. Nothing happens

Look at my comment about the use of '<' against the '<='

I don't have a hasNext() or next() in my code?

Line 73 has a call to next(): tastatur.next();
Add System.out.println("hasNext=" + tastatur.next());
before that line to see if the Scanner class has any data to be read.

@javaAddict: Thanks, I tried your code and it's working! I guess the problem is solved then. I don't get why i can't have "while (tallPosisjon <= famousFinalFour.length())" though, but I'll look into it.
Thanks everyone for your help, I'll mark this as solved

@Norm: aha, of course. Well I guess it's solved now anyway.

Edited 5 Years Ago by java.util: n/a

@javaAddict: Thanks, I tried your code and it's working! I guess the problem is solved then. I don't get why i can't have "while (tallPosisjon <= famousFinalFour.length())" though, but I'll look into it.
Thanks everyone for your help, I'll mark this as solved

@Norm: aha, of course. Well I guess it's solved now anyway.

Because when tallPosisjon = famousFinalFour.length() it will enter the loop and you will call the:
famousFinalFour.charAt(tallPosisjon);

But indexes in java are from 0 to length-1. If a String has length 4 ("abcd") you can call:
charAt(0), charAt(1), charAt(2), charAt(3) but not charAt(4)

It like when you loop:

for (int i=0;i<array.length;i++) {

}

You don't use <=

This question has already been answered. Start a new discussion instead.