5

I want to parse numbers in a line of a text file line by line. For example, imagine _ as a space

my text file content looks like:

___34_______45
_12___1000
____4______167
...

I think you got the idea. Each line may have variable number of spaces separating the numbers, meaning there is no pattern at all. The simplest solution could be read char by char and check if it is a number and go like that until the end of the number string and parse it. But there must be some other way. How can I read this in Java automatically so that I can get in a certain datastructure say array

[34,45]
[12,1000]
[4,167]
Bob
  • 991
  • 8
  • 23
  • 40

3 Answers3

11

Use java.util.Scanner. It has the nextInt() method, which does exactly what you want. I think you'll have to put them into an array "by hand".

import java.util.Scanner;
public class A {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int v1 = in.nextInt(); //34
    int v2 = in.nextInt(); //45
    ...
  }
}
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
Jonathan Paulson
  • 1,048
  • 6
  • 15
  • Just implemented it within my code. Fabulous, never used this scanner before. Cool thx! – Bob Sep 17 '12 at 03:27
4

If you only need your numbers in a data structure, e.g. a flat array, then you can read the file with a Scanner and a simple loop. Scanner uses whitespace as the default delimiter, skipping multiple whitespaces.

Given List ints:

Scanner scan = new Scanner(file); // or pass an InputStream, String
while (scan.hasNext())
{
    ints.add(scan.nextInt());
    // ...

You'll need to handle exceptions on Scanner.nextInt.

But your proposed output data structure uses multiple arrays, one per line. You can read the file using Scanner.nextLine() to get individual lines as String. Then use String.split to split around whitespaces with a regex:

Scanner scan = new Scanner(file); // or InputStream
String line;
String[] strs;    
while (scan.hasNextLine())
{
    line = scan.nextLine();

    // trim so that we get rid of leading whitespace, which will end
    //    up in strs as an empty string
    strs = line.trim().split("\\s+");

    // convert strs to ints
}

You could also use a second Scanner to tokenize each individual line in an inner loop. Scanner will discard any leading whitespace for you, so you can leave off the trim.

pb2q
  • 58,613
  • 19
  • 146
  • 147
  • You can avoid the empty element I think by first doing a `trim()` on the string before splitting it: `strs = line.trim().split("\\s+")`. – Roddy of the Frozen Peas Sep 17 '12 at 03:09
  • @RoddyoftheFrozenPeas I'll add the trim – pb2q Sep 17 '12 at 03:09
  • I think, scanner.nextInt does this for me. However giving you the point for the regex \\s+ – Bob Sep 17 '12 at 03:28
  • 1
    `Scanner.nextint` will consume all the integers in a single loop, but according to your proposed result, you also need to know when you cross newline boundaries – pb2q Sep 17 '12 at 03:30
1

Bum it old-school with BufferedReader and String's split() function:

BufferedReader in = null;
try {
    in = new BufferedReader(new FileReader(inputFile));
    String line;
    while ((line = in.readLine()) != null) {
        String[] inputLine = line.split("\\s+");
        // do something with your input array
    }
} catch (Exception e) {
    // error logging
} finally {
    if (in != null) {
        try {
            in.close();
        } catch (Exception ignored) {}
    }
}

(If you're using Java 7, the finally block is unnecessary if you use the try-with-resources.)

This will change something like ______45___23 (where _ is whitespace) into an array ["45", "23"]. If you need those as integers, it's quite trivial to write a function to convert the String array into an int array:

public int[] convert(String[] s) {
    int[] out = new int[s.length];
    for (int i=0; i < out.length; i++) {
        out[i] = Integer.parseInt(s[i]);
    }
    return out;
}
Roddy of the Frozen Peas
  • 14,380
  • 9
  • 49
  • 99
  • Thanks. Scanner does the job for me. + for your finally block information for Java 7 – Bob Sep 17 '12 at 03:28