0

Let me clarify the question I am asking. I have a java program I am working on that takes input from the keyboard via a readline library called JLine2. The library takes the entire line types as a command instead on breaking it up into space separated commands and arguments. What I am looking for is a safe way to break up the string that is passed as input.

I have tried using an array but since I am in the early stages of concept I don't yet know how many arguments my largest command will have so using a pre-initialized array I don't think will work. The problem I have ran into is when I check for null values in the array or when I check to see if a particular command or argument is present. Java keeps throwing an exception about the array index being out of scope or something. Because the array does not actually have a value for say array index 1 which is an argument to command in array index 0.

So what I am looking for is a way to take a string and safely split it into parts without having Java yelling at me when and array exception has occurred.

Here is the very slim code I can provide...

ConfigShell.class

package shell; 

import java.io.IOException;

import configFS.ConfigFS;
import jline.console.ConsoleReader;

public class ConfigShell {

    private ConfigFS config;

    public ConfigShell() throws IOException {

        config = new ConfigFS();

    }

    public void init() throws IOException {

        ConsoleReader console = new ConsoleReader();

        // When the program starts we want to be placed at / (root).
        console.setPrompt(">> ");

        // In this case an infinite loop is better than a loop based on whether line is equal to null.
        // This allows line to be equal to null and still stay inside the shell.
        while (true) {

            String line = console.readLine();

            if (line != null) {

                // If pre-initialize the array I can check for null as a value for an array index.
                // If I did this at time I needed the array and there were not enough index occupied the system would return an exception.
                String[] cmdArgs = new String[4];

                // We need to split up the incoming line because JLine2 does not do it for me.
                // This allows me to evaluate the entire command piece by piece rather all at once.
                cmdArgs = line.split("\\s+");

                if (cmdArgs[0] != null && cmdArgs[0].equals("add")) {

                    if (cmdArgs[1] != null && cmdArgs[1].equals("server")) {

                        if (cmdArgs[2] != null) {

                            config.addServer(cmdArgs[2]);
                            System.out.println("Added server " + cmdArgs[2] + " to the configuration successfully.");

                        }

                    }

                }

                if (cmdArgs[0].equals("exit")) {

                    System.exit(0);

                }

            }

        }

    }

}

Note for testing: My Start.class main method makes a call to the init method in the above file.

AtomicPorkchop
  • 2,625
  • 5
  • 36
  • 55

3 Answers3

1

You can do:

        String cmdArgs = line.split("\\s+");

and then, before accessing any particular index, check the size of the array so that you do not get ArrayIndexOutOfBoundException

Something like this:

if(cmdArgs.length>=2){
//It means you have at least 2 elements
//Now its safe to access cmdArgs[0] and cmdArgs[1]
}
Manish
  • 3,913
  • 2
  • 29
  • 45
  • `String.split()` should work unless the poster needs to deal with quoted strings. Consider a file on a file system that can have spaces in its name. If the command is `server C:\Program Files\apache\bin\apache`, splitting on spaces may cause problems. – Eric Jablow Apr 03 '13 at 04:21
  • @EricJablow Hmm until you mentioned it I had not considered that scenario. – AtomicPorkchop Apr 03 '13 at 05:09
  • The basic command structure would be more like this. "add server ". The server name would something more like a descriptive name rather than a file path. But it still raises the question of how to handle spaces in the names. – AtomicPorkchop Apr 03 '13 at 05:13
  • Is space a valid character in server names? – Manish Apr 03 '13 at 06:26
  • I have no idea. It depends on the program. Handling spaces and quoted strings is a general difficulty that might affect any `split`-based solution depending on the problem domain. Most programs that are configurable use configuration files with specific formats; consider `Apache`. – Eric Jablow Apr 03 '13 at 10:45
0

If all your problem is to have a storage for a variable number of strings you can use ArrayList<String> object.

You declare it like ArrayList<String> as = new ArrayList<String>();

Then when you split something from your command string you will simply use add method: as.add(yourString);

If you need to retrieve a particular element of the ArrayList you can use its get method: as.get(0);

You can process all elements with for each loop:

for(String str: as) {
println(str):
}

Have a look here for info and here for an example.

PM 77-1
  • 12,933
  • 21
  • 68
  • 111
0

As I think you can use StringTokenizer class and its methods for your requirement.

see the sample code below:

 if(line!=null)
    {
     StringTokenizer st=new StringTokenizer(line);// by default it takes space as delimiter....you can use as required as second argument in constructor...
     while(st.hasMoreTokens())
     {
      String token1=st.nextToken();
     // do your stuffs here..........
     // I don't know exactly about your required logic here......

   /* if(token1.equals("add"))
      {
         String token2=st.nextToken();
         if(token2.equals("server"))
         {
           String token3=st.nextToken();
             config.addServer(token3);
             System.out.println("Added server " + token3 + " to the configuration successfully.");
         }
       }
     */
    }// while closing...
   }// outer if closing...

Or as PM 77-1 told you can use ArrayList. But as my opinion LinkedList should be a better option here.

Shailesh Saxena
  • 3,472
  • 2
  • 18
  • 28
  • I could be wrong but I think StringTokenizer is depreciated in Java 7 which is what I am using. – AtomicPorkchop Apr 03 '13 at 05:10
  • @Solignis Yes, You are right. Thanks for the useful information. I got it here http://stackoverflow.com/questions/6983856/why-is-stringtokenizer-deprecated . – Shailesh Saxena Apr 03 '13 at 06:08