1

I need an equivalent to C's vsscanf() in Java. More detailled, I have this here:

private void parseString(String parseMe, String format, Object[] args) {
    // something like: vsscanf(parseMe, format, args);
}

Note that I have indeed read about an equivalent for sscanf(), so it could be done easily from there. But I ask myself whether there is a more elegant solution than filling args with a for loop.

Also, it would be nice if the solution allows using varargs instead of an array, too. See below.

parseString(str, format, x, y, z);
Community
  • 1
  • 1
Johannes
  • 2,901
  • 5
  • 30
  • 50
  • @HovercraftFullOfEels I want to scan, not print. Some confusion? – Johannes Jan 03 '13 at 23:32
  • 1
    This is unlikely to be possible, given Java's pass-references-by-value semantics. Also, the casts you'd be forced to do would introduce more awkwardness than the scanf syntax (as opposed to e.g. a `Scanner`) would save. – Louis Wasserman Jan 03 '13 at 23:35
  • @LouisWasserman awkwardness? What does that mean in this context? – Johannes Jan 03 '13 at 23:37
  • The only possible approach would be to take an `Object[]` -- not varargs -- and then to explicitly cast the results in that array: `(Float) array[0]`, `(String) array[1]`, `(Integer) array[2])`. I feel pretty strongly that that's uglier than just doing e.g. `scanner.nextFloat()`, `scanner.next()`, and `scanner.nextInt()`. – Louis Wasserman Jan 03 '13 at 23:41
  • I don't know a direct equivalent. One way to build it yourself is to use [java.util.Scanner](http://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html) and parse the format string then use a `switch` statement to call `nextInt()` etc. depending on the pattern found. – Florent Guillaume Jan 03 '13 at 23:41
  • In some common cases it might be simpler to just use `String`'s `split`. When things are more complicated, the `Scanner` way of doing it would just be more readable. – trutheality Jan 03 '13 at 23:45

1 Answers1

3

You can use java.text.MessageFormat. For example:

public static void main(String[] args) throws ParseException {
    String input="hello 1:2.3.4";
    MessageFormat form = new MessageFormat("{0} {1,number}:{2,number,integer}.{3,number}");
    Object[] data = form.parse(input);
    for(Object o : data) {
        System.out.println(o.getClass()+" : "+o.toString());
    }
}

Which produces the output:

class java.lang.String : hello
class java.lang.Long : 1
class java.lang.Long : 2
class java.lang.Double : 3.4

Of course, the format isn't as compact as that used by scanf, but it is out of the box Java.

Simon G.
  • 6,587
  • 25
  • 30