Tuupertunut
Tuupertunut

Reputation: 741

Java Scanner ignores first token if it is empty

I'm trying to read an InputStream of String tokens with a Scanner. Every token ends with a comma ,. An empty string "" is also a valid token. In that case the whole token is just the comma that ends it.

The InputStream is slowly read from another process, and any tokens should be handled as soon as they have been fully read. Therefore reading the whole InputStream to a String is out of the question.

An example input could look like this:

ab,,cde,fg,

If I set the delimiter of the Scanner to a comma, it seems to handle the job just fine.

InputStream input = slowlyArrivingStreamWithValues("ab,,cde,fg,");

Scanner scan = new Scanner(input);
scan.useDelimiter(Pattern.quote(","));
while (scan.hasNext()) {
    System.out.println(scan.next());
}

output:

ab

cde
fg

However the problems appear when the stream begins with an empty token. For some reason Scanner just ignores the first token if it is empty.

/* begins with empty token */
InputStream input = slowlyArrivingStreamWithValues(",ab,,cde,fg,");
...

output:

ab

cde
fg

Why does Scanner ignore the first token? How can I include it?

Upvotes: 3

Views: 802

Answers (2)

Lorenzo Notaro
Lorenzo Notaro

Reputation: 89

It's easier if you write it yourself, without using Scanner:

static List<String> getValues(String source){
    List<String> list = new ArrayList<String>();
    for(int i = 0; i < source.length();i++){
        String s = "";
        while(source.charAt(i) != ','){
            s+=source.charAt(i++);
            if(i >= source.length()) break;
        }
        list.add(s);
    }
    return list;
}

For example, if source = ",a,,b,,c,d,e", the output will be "", "a", "", "c", "d", "e".

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521437

Try using a lookbehind as the pattern:

(?<=,)

and then replace comma with empty string with each token that you match. Consider the following code:

String input = ",ab,,cde,fg,";
Scanner scan = new Scanner(input);
scan.useDelimiter("(?<=,)");
while (scan.hasNext()) {
    System.out.println(scan.next().replaceAll(",", ""));
}

This outputs the following:

(empty line)
ab

cde
fg

Demo

Upvotes: 1

Related Questions