开发者

Help with line.split CSV

开发者 https://www.devze.com 2022-12-20 01:44 出处:网络
I\'m a beginner, so please don\'t blast my work so far :) I\'m trying to read in a CSV file and then see if it matches certain commands. Some of the data in the CSV has a period and I think it\'s mess

I'm a beginner, so please don't blast my work so far :) I'm trying to read in a CSV file and then see if it matches certain commands. Some of the data in the CSV has a period and I think it's messing up when I'm trying to split it. When I try to dump my arrays to see what's there, it always gets cut off after the period. Here is a data sample. Any help would be appreciated. Again I'm a beginner so simplicity would be appreciated.

Sample data

create,Mr. Jones,blah,blah
create,Mrs. Smith,blah,blah
public class TestHarness {
        public static void main(String[] args) throws IOException, FileNotFoundException {

    Scanner input = new Scanner(new File("C:\\Users\\Ree\\Desktop\\SPR\\commands.txt"));

    String[] validCommands = { "create", "move", "useWeapon", "search", "heal" };

    boolean proceed = false;

    while (!proceed)
    {
       for (int i = 0; i < validCommands.length; i++)
       {
          String line = input.next();
          String[] nline = line.split (",");

          if (nline[0].equals("create")) 
          {
            String soldierName = nline[1];
            开发者_运维知识库String soldierType = nline[2];
            String weapon = nline[3];
            Soldier aSoldier = new Soldier(soldierName,weapon);

            System.out.println("Command: "+ nline[0] +","+ soldierName +","+ soldierType+","+ weapon);

            if (soldierType.equals("enlisted"))
            {
                Soldier s = new Enlisted(soldierName,weapon);
                System.out.println(s.toString());
            }
            else if (soldierType.equals("officer"))
            {
                Soldier s = new Officer(soldierName,weapon);
                System.out.println(s.toString());
            }
          }

          else if (nline[0].equals("useWeapon")) {
              System.out.print("weapon " + nline[0] + "\n");
          }
          else if (nline[0].equals("move")) {
              System.out.print("move " + nline[0] + "\n");
          }
          else if (nline[0].equals("search")) {
              System.out.print("search " + nline[0] + "\n");
          }
          else if (nline[0].equals("heal")) {
              System.out.print("heal " + nline[0] + "\n");
          }
        }
    }
}

}


Calling Scanner.next will only return the next word (separated by whitespace).

You need to call nextLine to read entire lines at a time.


There are several open source CSV parers available for Java:

  • http://supercsv.sourceforge.net/
  • http://commons.apache.org/sandbox/csv/


That was a rather quick mistake, wasn't it?

This is not an answer to your question but a recommendation to use a hash. First define an interface

public interface InputDance
{
  public void dance(String[] input);
}

I recommend that your main routine should be

public static void main(String[] args)
  throws IOException, FileNotFoundException{

  Scanner input = new Scanner(
  new File("C:\\Users\\Ree\\Desktop\\SPR\\commands.txt"));

  String line = input.nextLine();
  String[] nline = line.split (",");
  InputDance inputxn = inputActions.get(nline[0]);
  if (inputxn!=null)
    inputxn.dance(nline);
}

You would be using a hash to store all the actions outlined by the interface InputDance.

So that your input reading routine would be simplified to

  • retrieve action from hash of actions using word0 of input as key.
  • execute that action

If you have only five types of soldiers, it would ok to place all your logic in one routine. However, for more than 10 types of personnel, it would be cleaner to place the actions outside the routine.

If you are writing a computer game, or keeping personnel records on a military database, you would frequently encounter enhancement requests to include new personnel types or exceptions to the rule. Then your if-then-else-if chain would become increasingly longer and confusing. Especially when there are special requirements for soldiers dancing to a different tune. Or when your game canvas or personnel database needs to include non-battle units. But, of course, you still need to update the hash in the main class every time you have a new personnel type.

Notice that in my recommendation all your routine would do is to perform the dance(String[]) method. Any complication would be handled by the individual class implementing the dance.

Next define an implementing class

public class SoldierDance
  implements InputDance
{
  public void dance(String[] nline){
    String soldierName = nline[1];
    String soldierType = nline[2];
    String weapon = nline[3];

    System.out.println(
      "Command: "+ nline[0] +","+ soldierName +","+ soldierType+","+ weapon);

    Soldier s;
    if (soldierType.equals("enlisted")){
      s = new Enlisted(soldierName,weapon);
    }
    else if (soldierType.equals("officer")){
      s = new Officer(soldierName,weapon);
    }
    else{
      s = new Soldier(soldierName,weapon);
    }

    System.out.println(s.toString());
  }
}

Then define your main class. Notice that the hash is a static instance.

Also, there is a placeholder dance so that when you have a new personnel type, but you don't know what to do with it yet, you just hash the new personnel type to this placeholder dance.

Notice, for example in the "useWeapon" hash key, that an interface can be implemented anonymously too

public class TestHarness
{
  static public class PlaceHolderDance
    implements InputDance
  {
    public void dance(String[] nline){
      System.out.print("Action=" + nline[0] + "\n");
    }
  }

  static public Hashtable<String, InputDance> inputActions;

  // A static enclosure is to execute all the class definition once.
  static {
    inputActions = new Hashtable<String, InputDance>();

    InputDance placeHolderAction = new PlaceHolderDance();

    inputActions.put("create", new SoldierDance());
    inputActions.put("move", placeHolderAction);
    inputActions.put("search", placeHolderAction);
    inputActions.put("heal", placeHolderAction);

    // Can also anonymously implement an interface
    inputActions.put("useWeapon",
      new InputDance(){
        public void dance(String[] nline){
          System.out.print("weapon " + nline[0] + "\n");
        }
      }
    );

  }

  // The static main method
  public static void main(String[] args)
    throws IOException, FileNotFoundException{
  Scanner input = new Scanner(
    new File("C:\\Users\\Ree\\Desktop\\SPR\\commands.txt"));

      String line = input.nextLine();
      String[] nline = line.split (",");
      InputDance inputxn = inputActions.get(nline[0]);
      if (inputxn!=null)
        inputxn.dance(nline);
    }
}

And, if there is a one-one correspondence between a soldier class and its inputdance, you could even implement InputDance in the soldier class and provide the dance method.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号