1

I'm trying to take in a string input which consists of multiple lines of numbers separated by ',' and ';' .

Example:

1,2;3,4;5,6;
9,8;7,6;
0,1;
;

Code:

ArrayList<Integer> alist = new ArrayList<>();
        String delims = ";|\\,";
        int i = 0;
        Scanner input = new Scanner(System.in);
        input.useDelimiter(delims);
        while (input.hasNext()) {
            alist.add(i, input.nextInt());
            System.out.print(i + ' ');
            System.out.print(alist.get(i) + '\n');
            i++;
        }
        System.out.print('x');

When I run this in eclipse:

1,2;3,4;5,6;    ( <= what i typed in console)
321133123413351436153716    ( <= output)                

I'd expect something more like:

0 1
1 2
2 3
3 4
4 5 
5 6
x

Why am I getting this sort of output?

1
  • 1
    my use of Scanners hasNext() method has been when reading files; maybe you need a sentinel-controlled loop. Loop until the user enters -999 or some int that shouldn't be part of the entered data Commented Mar 30, 2015 at 0:06

2 Answers 2

2

One problem is that System.in is basically an infinite stream: hasNext will always return true unless the user enters a special command that closes it.

So you need to have the user enter something that tells you they are done. For example:

while(input.hasNext()) {
    System.out.print("Enter an integer or 'end' to finish: ");
    String next = input.next();
    if("end".equalsIgnoreCase(next)) {
        break;
    }

    int theInt = Integer.parseInt(next);
    ...

For your program, you might have the input you are trying to parse end with a special character like 1,2;3,4;5,6;end or 1,2;3,4;5,6;# that you check for.

And on these lines:

System.out.print(i + ' ');
System.out.print(alist.get(i) + '\n');

It looks like you are trying to perform String concatenation but since char is a numerical type, it performs addition instead. That is why you get the crazy output. So you need to use String instead of char:

System.out.print(i + " ");
System.out.print(alist.get(i) + "\n");

Or just:

System.out.println(i + " " + alist.get(i));

Edit for comment.

You could, for example, pull the input using nextLine from a Scanner with a default delimiter, then create a second Scanner to scan the line:

Scanner sysIn = new Scanner(System.in);
while(sysIn.hasNextLine()) {
    String nextLine = sysIn.nextLine();
    if(nextLine.isEmpty()) {
        break;
    }

    Scanner lineIn = new Scanner(nextLine);
    lineIn.useDelimiter(";|\\,");

    while(lineIn.hasNextInt()) {
        int nextInt = lineIn.nextInt();
        ...
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

oh man its always the little things, changing to the double speech completely fixed the output :) thanks
How would I use the next blank line to end the stream?
0

Since Radiodef has already answered your actual problem(" instead of '), here are a few pointers I think could be helpful for you(This is more of a comment than an answer, but too long for an actual comment):

When you use Scanner, try to match the hasNextX function call to the nextX call. I.e. in your case, use hasNextInt and nextInt. This makes it much less likely that you will get an exception on unexpected input, while also making it easy to end input by just typing another delimiter.

Scanners useDelimiter call returns the Scanner, so it can be chained, as part of the initialisation of the Scanner. I.e. you can just write:

Scanner input = new Scanner(System.in).useDelimiter(";|\\,");

When you add to the end of an ArrayList, you don't need to(and usually should not) specify the index.

int i = 0, i++ is the textbook example of a for loop. Just because your test statement doesn't involve i does not mean you should not use a for loop.

Your code, with the above points addressed becomes as follows:

ArrayList<Integer> alist = new ArrayList<>();
Scanner input = new Scanner(System.in).useDelimiter(";|\\,");
for (int i = 0; input.hasNextInt(); i++) {
    alist.add(input.nextInt());
    System.out.println(i + " " + alist.get(i));
}
System.out.println('x');

Edit: Just had to mention one of my favorite delimiters for Scanner, since it is so suitable here:

Scanner input = new Scanner(System.in).useDelimiter("\\D");

This will make a Scanner over just numbers, splitting on anything that is not a number. Combined with hasNextInt it also ends input on the first blank line when reading from terminal input.

2 Comments

"use hasNextInt [...] making it easy to end input by just typing anything other than a number" This won't work, actually, the Scanner will just skip the non-int and attempt to scan ahead (it will prompt again) instead of returning false.
You are right, thanks, I mixed up \\D and his delimiter. Using hasNextInt you have to end input with a delimiter. Updating to correct this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.