-1

I am creating a project that translate Morse Code into English and English into Morse Code. The program shall prompt the user to specify the desired type of translation, input a string of Morse Code characters or English characters, then display the translated results. All upper and lower case, numbers and punctuations could be ignored. And please do not use Hashtables and maps.

I manage to successfully finish writing the part to translate English to Morse. However, when translating Morse to English there seems to be a lot of errors going on. But I couldn't figure out why.

So anyone who's reading this, I would be so thankful if you help me solve the error! Any helps are appreciated. Thank you so much!

The error message that was displayed on the console was this :

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at java.lang.String.substring(String.java:1950) at Project1.MoToEng(Project1.java:57) at Project1.main(Project1.java:30)

public class Translator
{
public static String[] morse = { ".- ", "-... ", "-.-. ", "-.. ", ". ",
        "..-. ", "--. ", ".... ", ".. ",

        ".--- ", "-.- ", ".-.. ", "-- ", "-. ", "--- ", ".--. ", "--.- ",
        ".-. ", "... ", "- ", "..- ",

        "...- ", ".-- ", "-..- ", "-.-- ", "--.. ", "|" };

public static String[] alphabet = { "a", "b", "c", "d", "e", "f", "g", "h",
        "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
        "v", "w", "x", "y", "z", " " };

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.println("Input '1' to translate English to Morse Code.");
    System.out.println("Input '2' to translate Morse Code to English.");
    int kind = in.nextInt();

    if (kind == 1) {
        System.out.println("Please insert an alphabet string");
        String Eng = in.next();
        EngToMo(Eng);
    }
    if (kind == 2) {
        System.out.println("Please insert a morse string");
        String Mor = in.next();
        MoToEng(Mor);
    }

}

public static void EngToMo(String string1) { 
    String Upper1 = string1.toUpperCase();
    for (int i = 0; i < Upper1.length(); i++) {
        char character1 = Upper1.charAt(i);
        if (character1 != ' ') {
            System.out.print(morse[character1 - 'A'] + " ");
        } else {
            System.out.println(" | ");
        }
    }
}

public static void MoToEng(String string2) { 
int x = 0;
int y = 1;
String space = " ";
for (int i = 0; i < string2.length(); i++) {
    if(string2.substring(x,y).equals(space)){
        x++;
        y++;
    }
    else{
        y++;
        if(string2.substring(x,y).equals(morse[i])){
            System.out.println(alphabet[i]+ " ");
        }
    }
}
}
}
Danny
  • 93
  • 1
  • 9
  • 1
    did you get any stacktrace? – roeygol Jan 20 '15 at 09:35
  • Sorry I just started to learn java, what's stack trace? – Danny Jan 20 '15 at 09:36
  • @imibis It says this on the IDE I'm using: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at java.lang.String.substring(String.java:1950) at Project1.MoToEng(Project1.java:58) at Project1.main(Project1.java:31) – Danny Jan 20 '15 at 09:37
  • it's the error's in red that you're getting in console – roeygol Jan 20 '15 at 09:37
  • You seem to be using `==` instead of `equals` to compare strings. – Dawood ibn Kareem Jan 20 '15 at 09:37
  • add it to the original question – roeygol Jan 20 '15 at 09:38
  • Thank guys, I fixed the "==" part, but there still seems to be an error going on. Here's what it says on the console: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at java.lang.String.substring(String.java:1950) at Project1.MoToEng(Project1.java:59) at Project1.main(Project1.java:31) – Danny Jan 20 '15 at 09:43
  • @DavidWallace this is not main issue in this question – user902383 Jan 20 '15 at 10:03
  • @user902383 Yes, the program I wrote can't even run, an error just popped out – Danny Jan 20 '15 at 10:07
  • @Danny your issue is here : `if(string2.substring(x,y).equals(morse[i]))` variable i is index of character in `string` comparing, try to change this line to `java.util.Arrays.asList(morse[i]).contains(string2.substring(x,y))` – user902383 Jan 20 '15 at 10:08
  • @user902383 Thanks, but it still doesn't seem to be working. Here's what the console says: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3 at java.lang.String.substring(String.java:1950) at Project1.MoToEng(Project1.java:58) at Project1.main(Project1.java:30) – Danny Jan 20 '15 at 10:12
  • Might help if you provided the input – Bob Vale Jan 20 '15 at 10:17
  • @Danny try then `string2.substring(x, Math.min(y,string2.length())` – user902383 Jan 20 '15 at 10:19
  • 1
    As y starts at 1 and you increase it each time you loop the last value for y will be the length of the string which means you are calling substring with y being one higher than the last index of the string. – Bob Vale Jan 20 '15 at 10:20
  • @BobVale Then is there anyway to fix that? – Danny Jan 20 '15 at 10:32
  • @user902383 That doesn't seem to be working either :( – Danny Jan 20 '15 at 10:33

2 Answers2

0

There are a few issues with this code.

The first is what is causing the exception,

Because y starts at 1 and increases by one each loop it will equal the length of string2 on its last iteration. This means, as strings are zero indexed, it will be one high than the last index in the string, hence the crash in string2.substring(x,y)

Secondly you are including spaces in your morse list and so the code is never able to match the last morse code in the string, so it would never match the string -. for example.

However it will match early if you just remove the spaces i.e. match -. in the string -.--.

You could simply use the split function to split the input string into an array split on " "

Sample code

public static void MoToEng(String string2) {
        int x = 0;
        char space = ' ';
        for (int y = 1; y <= string2.length(); y++) {
            String match = null;
            if (y == string2.length()) {
                // Reached the end of the string
                match = string2.substring(x);
            } else if (string2.charAt(y) == ' ') {
                // Reached the end of the word
                match = string2.substring(x,y);
                x = y+1;
                if (x == string2.length()) {
                    x--;
                }
            }

            if (match != null) {
                for (int j = 0;j < morse.length;j++) {
                    if (morse[j].equals(match+" ")) {
                        System.out.println(alphabet[j] + " ");
                    }
                }
            }
        }
    }

NOTE: You may run into problems as the scanner you are using to read from system.in will tokenize and only give you up to the first space. So if you use the Scanner class you only actually need

for (int j = 0;j < morse.length;j++) {
  if (morse[j].equals(string2+" ")) {
    System.out.println(alphabet[j] + " ");
  }
}

If you want to use the full match on input without relying on scanner to do the hard work change your second match to

if (kind == 2) {
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  System.out.println("Please insert a morse string");
  try {
    MoToEng(br.readLine());
  } catch (IOException e) {
    e.printStackTrace();
  }
}

Obviously you can use an array list, split function and indexOf as suggested by user902383 but this answer is just to correct the crash in your code.

Bob Vale
  • 18,094
  • 1
  • 42
  • 49
0

i simplified your method MoToEng, you need to change morse to be a list, and also i removed white spaces from entries

public static List<String> morse = Arrays.asList(".-", "-...", "-.-.",
            "-..", ".", "..-.", "--.", "....", "..", 
  "--..", "|");

and you need to change System.out.print(morse[character1 - 'A'] + " "); to System.out.print(morse.get(character1 - 'A') + " "); in EngToMo and it will work

and that should make it work

public static void MoToEng(String string2) {
        int x = 0;
        int y = 1;

        for (String token : string2.split("\\s+")) {

            int index = morse.indexOf(token);
            if (index > -1) {
                System.out.println(alphabet[index] + " ");
            }

        }
    }
user902383
  • 8,420
  • 8
  • 43
  • 63