8

I have a formatted text like this:

x.i9j11k2d1" index="603" value="0"/>
x.i9j11k2d2" index="604" value="0"/>
x.i9j11k2d3" index="605" value="0"/>
x.i10j1k1d1" index="606" value="-0"/>

And, I'm interested in Scanning only the digits. For example:

int i,j,k,d,index,value;

For the first line I want:

i=9, j=11, k=2, d=1, index=603, value=0

For this purpose, I used the following code:

Scanner file=new Scanner(new File("C:/sol.txt"));
while(file.hasNext())
    {           
        System.out.println("");
        int i=0;
        int j=0;
        int k=0;
        int d=0;
        file.useDelimiter("");          
        while(!(file.hasNextInt()))
        {
            System.out.print(file.next());
        }
        //System.out.print(file.next());
        file.useDelimiter("j");
        i=file.nextInt();
        System.out.print(i);
        file.useDelimiter("");

        System.out.print(file.next());      //j
        file.useDelimiter("k");
        j=file.nextInt();
        System.out.print(j);
        file.useDelimiter("");

        System.out.print(file.next());      //k
        k=file.nextInt();
        System.out.print(k);
        System.out.print(file.next());      //d
        d=file.nextInt();
        System.out.print(d);
        while(!(file.hasNextInt()))
        {
            System.out.print(file.next());
        }
        file.useDelimiter("\"");
        int index=file.nextInt();
        System.out.print(index);
        file.useDelimiter("");
        while(!(file.hasNextInt()))
        {
            System.out.print(file.next());
        }
        int value=file.nextInt();
        System.out.print(value);
        System.out.print(file.nextLine());      
    }
    file.close();
    }
    catch (FileNotFoundException exc)
    {System.out.println("File non trovato");}

It works perfectely until i is one digit, but then, when i have to scan the fourth line, I don't know why it returns the following:

...
//System.out.print(file.next());
file.useDelimiter("j");
i=file.nextInt();                   // it returns i=1 instead of 10
System.out.print(i);
file.useDelimiter("");

System.out.print(file.next());      //j    --> prints 0 instead of j
file.useDelimiter("k");
j=file.nextInt();                   //     --> finds j instead of 1 and  
                                    //         crashes with "InputTypeMismatch"

the file is formatted in XML, i cannot post the entire file cause it's thousands of lines, but it's like the following:

    <?xml version = "1.0" encoding="UTF-8" standalone="yes"?>
<CPLEXSolution version="1.2">
 <header
   problemName="prob"
   solutionName="incumbent"
   solutionIndex="-1"
   objectiveValue="58.2123812523709"
   solutionTypeValue="3"
   solutionTypeString="primal"
   solutionStatusValue="102"
   solutionStatusString="integer optimal, tolerance"
   solutionMethodString="mip"
   primalFeasible="1"
   dualFeasible="0"
   MIPNodes="3285"
   MIPIterations="22164"
   writeLevel="1"/>
   <variables>
  <variable name="x.i0j1k1d1" index="0" value="0"/>
  <variable name="x.i0j1k1d2" index="1" value="0"/>
  <variable name="x.i0j1k1d3" index="2" value="0"/>
  <variable name="x.i0j1k2d1" index="3" value="1"/>
  </variables>
  </CPLEXSolution>
jcsun
  • 155
  • 8
  • You're probably better off with using a regex for this type of problem. – JonasCz May 11 '15 at 15:59
  • The problem seems to be with your delimiter `file.useDelimiter("")` which uses nothing (zero size) as a delimiter. Better use RE. – akhil_mittal May 11 '15 at 16:00
  • 2
    This is one of the best questions I've seen by a new user in a while. Godspeed. – snickers10m May 11 '15 at 16:01
  • Is your formatted file a xml file? Can you post the complete structure as it will help all. – akhil_mittal May 11 '15 at 16:04
  • 1
    Can't you format the file as XML/JSON ? – Koen Demonie May 11 '15 at 16:07
  • 1
    I don't see what is wrong, you call for the next int after the delimeter "j" which is 1. if you wanted to get the 10 then you sshould have called for the delimeter "i" .... – Koen Demonie May 11 '15 at 16:14
  • @akhil_mittal i've taken the idea of `file.useDelimiter("")` from this answer. http://stackoverflow.com/questions/2597841/scanner-method-to-get-a-char Anyway when the problem appear the delimiter should be `"j"` and not `""` anymore.. isn't it? – jcsun May 11 '15 at 17:20
  • @KoenDemonie if i understood clear the use of scanner delimiters when i call `file.useDelimiter("j")` my scanner has just arrived to the 1 after `i`, so what i want to do is "get the next int that goes from here to j (excluded)" and to do this i need the `j` delimiter, not `i`. But please correct me if i'm wrong! – jcsun May 11 '15 at 17:27
  • and also: at the first line for example, when i scan for j=11, i do the excat same thing, specifing `k` as delimiter, and it works perfectly. So i cannot understand why it shouldn't work for the `i` – jcsun May 11 '15 at 17:33
  • a delimeter is a stop parameter for your next get function. if you set the delimeter on "j" the scanner does not jump to the next char. the next time you cal a getInt() or something it will read until it found its delimeter. – Koen Demonie May 11 '15 at 17:35
  • yes but.. i mean: i'm scanning my inputs untill i read read the first int (the 1 after i), then i set the delimiter "j", then i call the getInt(), so i expect my int will go from 1 to j (that is 10) and not 1. why is this wrong? – jcsun May 11 '15 at 17:45

1 Answers1

2

To make it simple use regex. With pattern "\d+" it will extract all numbers which you can use as you need it. Look at the code. Pattern p matches next digit, Matcher m applies this pattern to the string and then m.find() method extracts next group (digit number with pattern \d) and here is your number.

import java.util.regex.*;

public class test {
    public static void main(String[] args) throws Exception {
        int i = 0,j,k,d,index,value = 0;
        Pattern p = Pattern.compile("-?\\d+");
        Matcher m = p.matcher("x.i9j11k2d1\" index=\"603\" value=\"010\"/>");
        if(m.find()) i=Integer.parseInt(m.group());
        if(m.find()) j=Integer.parseInt(m.group());
        if(m.find()) k=Integer.parseInt(m.group());
        if(m.find()) d=Integer.parseInt(m.group());
        if(m.find()) index=Integer.parseInt(m.group());
        if(m.find()) value=Integer.parseInt(m.group());

        System.out.println("i="+i+" value="+value);
    }
}
Alex
  • 4,408
  • 2
  • 16
  • 57
  • thank you for your answer, but i'm not sure i get it (i'm not familiar with regex). Can please add some explanation to your code? – jcsun May 11 '15 at 17:51
  • Let me know if you need more. But, basically, you can use it as is. – Alex May 11 '15 at 18:04
  • That works perfectly! thank you very much! i should definitely study deeper regex! anyway , just for educational purpose, i'd like to understand why my method doens't work. So if anyone can enlight me i'd be very grateful ! – jcsun May 11 '15 at 20:26