Puppy_With_Pinecone
Puppy_With_Pinecone

Reputation: 3

Java morse code program - the program gets stuck on input

This program is using string methods to convert from English to morse code. when executing the code I seem to be stuck in an input mode before the [int KeyIndex = 0;] line. I am only testing for the English to morse code loop, so I have not included the morse to english portion of the code.

`public static void main(String[] args) { Scanner input = new Scanner(System.in);

  char[] EngMorseArray =
  { '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', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

  String[] MorseEngArray =
  { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.",
        "--.-", ".-.", "…", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---", "...--",
        "....-", ".....", "-....", "--...", "---..", "----." };

  // First we identify if we are going eng - morse or vice versa
  System.out.println("for Eng -> Morse, enter 1.  for Morse -> Eng, enter 2");
  String WhichConversion = input.next();

  if (WhichConversion.equals("1")) // English to Morse
  {
     System.out.println("What is the text you would like coded?"
           + " (lowercase a-z and 0-9 with a space between words, " + "please) ");
     
     String CharString = input.nextLine(); // this line is here twice
     CharString = input.nextLine(); // to avoid nextInt/nextLine issue
     
     char[] CharStringArray = new char[CharString.length() + 1];
     
     
     for (int index = 0; index < CharString.length(); index++) // Convert string to char array
     {
        CharStringArray[index] = CharString.charAt(index);
        System.out.print(CharStringArray[index]);
     }
     /*
      * convert from char Array to string again for (int index = 0; index <=
      * CharStringArray[index]; index++) { String charString = ""; charString +=
      * CharStringArray[index]; }
      */
     
     int KeyIndex = 0;
     int InputIndex;

     for (InputIndex = 0; InputIndex < EngMorseArray.length; InputIndex++)
     {

        while (KeyIndex <= EngMorseArray.length)
        {
           
           if (EngMorseArray[KeyIndex] == CharStringArray[InputIndex])
           {
              System.out.println(MorseEngArray[KeyIndex] + " ");
              KeyIndex++;
           } else if (CharStringArray[InputIndex] == ' ')
           {
              System.out.println(" | ");
              KeyIndex++;
           }`

Upvotes: 0

Views: 136

Answers (4)

Old Dog Programmer
Old Dog Programmer

Reputation: 1250

I'd like to illustrate how using arithmetic on char types can simplify this code. It's not really related to the question about input.

First, the Morse code array should be static data of the class. After all, the same data will be needed to encode to Morse as decode from Morse.

public class Puppy_with_pinecone {
    
    private static final String[] MORSE_CODE =  { 
          // letters a to z (lowercase)
          "•‒", "‒•••", "‒•‒•", "‒••", "•" , "••‒•", "‒‒•", "••••", "••"
        , "•‒‒‒", "‒•‒ ", "•‒••", "‒‒", "‒•", "‒‒‒", "•‒‒•", "‒‒•‒", "•‒•"
        , "•••", "‒", "••‒", "•••‒", "•‒‒", "‒••‒", "‒•‒‒", "‒‒••"
         // digits 0 to 9      
        , "‒‒‒‒‒", "•‒‒‒‒", "••‒‒‒", "•••‒‒", "••••‒" 
        , "•••••", "‒••••", "‒‒•••", "‒‒‒••", "‒‒‒‒•"    
    };
    
    private static final char SPACE = ' ';

    public static void main(String[] args) {
    ...
}

The following works because the letters A to Z are consecutive in ASCII, as are the letters a to z and the digits 0 to 9.[1] And Unicode is based on ASCII.

The char type in Java is an integer type primitive. So, char data can be used for arithmetic.

    
    public static String toMorse (String input) {

        StringBuilder output = new StringBuilder(input.length() * 6);           
            
        for (int inpIndex = 0; inpIndex < input.length(); inpIndex++) {
            char letter = Character.toLowerCase(input.charAt(inpIndex));
            if (letter >= 'a' && letter <= 'z') {
                output.append (MORSE_CODE [letter - 'a']).append(SPACE);
            } else if (letter >= '0' && letter <= '9') {
                output.append (MORSE_CODE [letter - '0' + 26]).append (SPACE);
            }
            else if (Character.isWhitespace(letter))  {
                output.append (" | ");
            }
        }
        return output.toString();
    }  

  • Returning a String is in keeping with separation of responsibilities design. Having the output handled outside the method that does the conversion makes it easier to reuse the conversion method. You might, for example, want to write the Morse code to a file, or pass it to a method that generates the sound of Morse code.

[1] Note this is not true of EBCDIC.

Upvotes: 0

Reilas
Reilas

Reputation: 6266

"... when executing the code I seem to be stuck in an input mode before the [int KeyIndex = 0;] line. ..."

Use the next method if you're parsing more than one value from the input line.
Othewise, use the nextLine method.

String WhichConversion = input.nextLine();

Then, the CharString assignment will only require one nextLine call.

Upvotes: 0

Puppy_With_Pinecone
Puppy_With_Pinecone

Reputation: 3

Ok so here is the new and improved program based on everyone's input. First, the main program:

public static void main(String[] args)
{
Scanner input = new Scanner(System.in);

String WhichConversion; // 1 means EngToMorse, 2 means MorseToEng

String EngInput; // raw string input for EngToMorse
String CodeOutput; // Output from EngToMorse
char[] EngInputArray; // EngInput converted to char array

String CodeInput; // raw code input for MorseToEng
String EngOutput; // Output from MorseToEng

// First we identify if we are going eng - morse or vice versa
System.out.println("for Eng -> Morse, enter 1.  for Morse -> Eng, enter 2");
WhichConversion = input.next();

// English to Morse
if (WhichConversion.equals("1"))
{
   System.out.println("What is the text you would like coded?"
   + " (lowercase a-z and 0-9 with a space between words, " + "please) 
   ");

EngInput = input.nextLine(); // this line is here twice
EngInput = input.nextLine(); // to avoid nextInt/nextLine issue

// declare array after EngInput is defined
EngInputArray = new char[EngInput.length() + 1];

// Convert EngInput to EngInputArray
for (int index = 0; index < EngInput.length(); index++)
{
    EngInputArray[index] += EngInput.charAt(index);
}
System.out.print(EngInputArray);
System.out.println(" ");

convertToMorse(EngInputArray);
}
 '''

And here is the method for the conversion from English to morse code:

private static void convertToMorse(char[] EngInputArray)
{
    char[] EngArray =
    { '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', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

    String[] MorseArray =
    { ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", 
        "-.- ", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "…", "-", "..- 
        ", "...-", ".--", "-..-", "-.--", "--..", "-----", ".----", "..---", 
        "...--", "....-", ".....", "-....", "--...", "---..", "----." 
    };

int KeyIndex = 0;
int InputIndex = 0;

for (InputIndex = 0; InputIndex < EngArray.length; InputIndex++)
{
    KeyIndex = 0;
    System.out.print(" ");

    while (KeyIndex < EngArray.length & InputIndex < EngInputArray.length)
    {
        if (EngArray[KeyIndex] == EngInputArray[InputIndex])
        {
             System.out.print(MorseArray[KeyIndex] + " ");
             KeyIndex = EngArray.length;
             break;
        } else if (EngInputArray[InputIndex] == ' ')
        {
            System.out.print(" | ");
            KeyIndex = EngArray.length;
            break;
        } else if (EngInputArray[InputIndex] != ' ' & EngArray[KeyIndex] != 
            EngInputArray[InputIndex])
        {
           KeyIndex++;
        }
       }
    }
} // End EngToMorse

Upvotes: 0

Rifat Rubayatul Islam
Rifat Rubayatul Islam

Reputation: 507

Your problem seems to be in the nested loops.

  1. Your loop condition should be CharStringArray.length instead of EngMorseArray.length in the outer loop.
  2. Your KeyIndex should be initialized inside the outer loop.
  3. KeyIndex should incremented when no match is found.
  4. When you find a match, you should break out of inner loop.

Here is the updated code snippet.

            /*
             * convert from char Array to string again for (int index = 0; index <=
             * CharStringArray[index]; index++) { String charString = ""; charString +=
             * CharStringArray[index]; }
             */
            System.out.println();
            int InputIndex;
            for (InputIndex = 0; InputIndex < CharStringArray.length; InputIndex++) {
                if (CharStringArray[InputIndex] == ' ') {
                    System.out.print(" | ");
                    continue;
                }

                int KeyIndex = 0;
                while (KeyIndex < EngMorseArray.length) {
                    if (EngMorseArray[KeyIndex] == CharStringArray[InputIndex]) {
                        System.out.print(MorseEngArray[KeyIndex] + " ");
                        break;
                    }
                    KeyIndex++;
                }
            }

There are other places where the code can be improved. Like using library method String.toCharArray() to convert string to char array. You can use maps instead of arrays to keep key, value pair.

Upvotes: 1

Related Questions