简体   繁体   中英

How to read String and input from a single line of input from scanner

Language : Java.

Aim: Boolean Array gridA[] should become true on whatever index is read from input (ie if input is "init_start 2 4 5 init_end" then gridA[] indexes 2,4 and 5 should become true). That much I managed to get working but I have two problems:

input: init_start int int int int int (...) int init_end for example: init_start 2 6 12 init_end

Problems: any integer from input that exceeds the value of (instance variable) int L (which determines the index-length of the array) should be ignored, to prevent integers from outside the domain of Array gridA[] from having influence. Using if(scanner.nextInt != L){} didn't seem to work.

I also need this method, or the body of the method to start when input begins with "init_start" and stop when input ends with "init_end". How do write code so that it can read both String and integers from the same input?

I meant to do this using if(scanner.Next=="init_start") followed by a = scanner.NextInt; which, as I suspected, didn't work.

Attempts at solving: After googling I tried putting String initialInputStart in a Scanner: localScanner(initialInputStart); but I failed to get that working. Other information I found suggested I'd close and reopen the scanner but I need the information to be read from a single line of input so I doubt that will help.

code:

java.util.Arrays.fill(gridA,false); 
java.util.Arrays.fill(gridB,false);
String initialInput;
String initialInputStart;
int a;
int i;//only for testing
i = 0;//only for testing

System.out.println("type integers"); //only for testing
while( scanner.hasNextInt() && i<5){ //I can't find a way to make loop stop without missing input so I'm using i temporarily
  a = scanner.nextInt();
  gridA[a] = true;
  System.out.print(a);
  System.out.print(gridA[a]+" ");
  i++;
}//end while    

I wrote a little program which pretty much does what you described as your aim; I read line by line and split each into tokens I further process. The tokens describe what the data means/what state we are in. The actual data is parsed in the default: case in the switch(token) block and branches in behaviour from state to state (which is merely visible here as we only have two states: "init" and "not init", beside the keywords):

public static void main(String[] args) {
    int L = 13; // not sure if this is needed
    boolean[] gridA = new boolean[L];

    Reader source;
    /**
     * from file:
     *     source = new FileReader("grid.csv");
     */
    /**
     * from classpath resource:
     *     source = new InputStreamReader(MyClass.class.getResourceAsStream("grid.csv"));
     */
    /**
     * from string:
     *     source = new StringReader("init_start 2 6 12 init_end");
     */
    /**
     * from std-in:
     *     source = new InputStreamReader(System.in);
     */
    try(BufferedReader stream = new BufferedReader(source)) {
        boolean init = false;

        // loop
        input_loop:
        while(true) {
            // read next line
            String line = stream.readLine();
            if(line == null) {
                // end of stream reached
                break;
            }
            if(line.trim().isEmpty()) {
                // ignore empty lines
                continue;
            }

            String[] tokens = line.split(" ");
            for (String token : tokens) {
                switch (token) {
                    // evaluate keywords
                    case "init_start":
                        init = true;
                        break;
                    case "init_end":
                        init = false;
                        break;
                    // for input from console
                    case "exit":
                        break input_loop;
                    default:
                    // parse input, based on state (expand "init" to an enum for more states)
                        if(init) {
                            // read init input
                            int index = Integer.parseInt(token);
                            if(index >= 0 && index < gridA.length) {
                                gridA[index] = true;
                            } else {
                                throw new RuntimeException("illegal grid index: " + index);
                            }
                        } else {
                            // read undefined input
                            throw new RuntimeException("unrecognized token: " + token);
                        }
                        break;
                }
            }

        }
    } catch(IOException ex) {
        throw new RuntimeException("an i/o exception has occurred", ex);
    }

    System.out.println(Arrays.toString(gridA));
}

" How do write code so that it can read both String and integers from the same input?"

do you want to have an Input like this: "123, foo" if thats the case use:

String input = scanner.nextLine();
String[] parts = input.split(",");//" " to split it at an empty space
String part1 = parts[0]; // 123
int Number = Integer.parseInt(part1) // you could inline it, but i chose this version for better refference
String part2 = parts[1]; //foo

if your Input looks like this "123 or foo" you have to read the input as String and check the String afterwards if its a Number:

String input = scanner.nextLine();
if (text.contains("[a-zA-Z]+") == false){ //looks if the input does NOT contain any characters
int nummber = Integer.parseInt(input);
} else{
String text = input;
}

afterward you can compare your text:

For the first mentioned case:

 if("init_start".equals(parts[1])){ //*
yourMethod();
}

For the other case:

  if("init_start".equals(text)){ //*
yourMethod();
}

*Also: "I meant to do this using if(scanner.Next=="init_start")"

*Very important! To compare Objects, such as String use .equals(). "==" only works on primitive types

Edit: I've read your example. You could go with a combination of my solutions. split the string at space(" ") and check parts[x] if it is an integer. But i wouldnt recommend this method! Why dont you split your input in three parts: init_start would start your function. After that your method would expect an input of Integers like "int int int" after you inserted the Integers your function could automatically stop or wait for the input "init_stop". That seems to me more reasonable. If you want to go with the single line solution you can evaluate the number of your int's by get ting parts[].lenght()-2

use this implementation:

public static void main(String args[]){
    try{
        Scanner in = new Scanner(System.in);
        System.out.println("Enter a line");
        String dat = in.readLine();
        System.out.println(dat);
    }
    catch(IOException e){
        System.out.println("IO ERROR !!!");
        System.exit(-1);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM