Jesal Patel
Jesal Patel

Reputation: 51

data extracted from text file gives error when storing it in variables

So I'm using a Scanner object to read data from a text file consisting of Employees of a company (their ID, Name and Manager ID. The problem I have is the data I store within these give an InputMismatchException.

Here is the code:

public class DataExtracter {
private Scanner x;
private String fileName = "C:\\Users\\Jesal\\Documents\\Waqar's thing\\BT Technology Graduate Programme 2015 - Software coding exercise/atchm_3803.txt".replaceAll("[|]", "");
private File f;

private int lineCounter;
private String employeeIdLst[];
private String employeeNameLst[];
private String managerIdLst[];

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    DataExtracter bt = new DataExtracter();
    de.openFile();
    de.readFile();
    de.closeFile();
}

public DataExtracter() {        
    f =new File(fileName);
    lineCounter = 0;
    lineCounter();
    employeeIdLst = new String[lineCounter];
    employeeNameLst = new String[lineCounter];
    managerIdLst = new String[lineCounter];
}

public void openFile() {
    try {
        x = new Scanner(f);
    } catch (Exception e) {
        System.out.println("could not find file");
    }
}

public void readFile() {
    x.nextLine();

    int index = 0;
    while (x.hasNext() && index < lineCounter) {           
        String theFile = x.next().replaceAll("[|]", " ");

        int employeeId = x.nextInt();
        String empName = x.next();
        int managerId = x.nextInt();

        System.out.print(theFile); 
    }

    index++;
}

public void closeFile() {
    x.close();
}

public int lineCounter() {    
    openFile();

    x.nextLine();

    while(x.hasNext() && !x.nextLine().isEmpty()){
        lineCounter++;       
    }

    closeFile();

   // System.out.println(lineCounter);
    return lineCounter;
}

}

When I run the program without the following lines of code:

int employeeId = x.nextInt();
String empName = x.next();
int managerId = x.nextInt();

The following is printed to the console:

1 Dangermouse   2 GonzotheGreat 1  3 InvisibleWoman 1  6 BlackWidow 2  12 HitGirl 3  15 SuperTed 3  16 Batman 6  17 Catwoman 6 BUILD SUCCESSFUL (total time: 0 seconds)

Here is the stack trace:

Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at binarytree.BinaryTree.readFile(BinaryTree.java:76)
at binarytree.BinaryTree.main(BinaryTree.java:41)

Java Result: 1

Here is the data of the text file:

  | Employee ID | Name            | Manager ID | 
  | 1           | Dangermouse     |            |
  | 2           | Gonzo the Great | 1          |
  | 3           | Invisible Woman | 1          |
  | 6           | Black Widow     | 2          |
  | 12          | Hit Girl        | 3          |
  | 15          | Super Ted       | 3          |
  | 16          | Batman          | 6          |
  | 17          | Catwoman        | 6          |

I am failing to understand how the nextInt() and Strings can't be retrieved as the order of data types retrieved are the same throughout and if I'm correct the whitespaces are discarded when reading the input. I want to also later use the data I've extracted to store each column data in arrays or just in an ArrayList.

Upvotes: 0

Views: 137

Answers (4)

JimW
JimW

Reputation: 186

Given:

| 1           | Dangermouse     |            |

and your code:

String theFile = x.next().replaceAll("[|]", " ");
int employeeId = x.nextInt();
String empName = x.next();
int managerId = x.nextInt();

System.out.print(theFile); 

Were you thinking that theFile would replace all |s with spaces for the line? It's only replacing the first |. The call to employeeId is ok, the call for empName grabs the next token which is another |. The next token is Dangermouse but you try to parse that into an int hence your error.

The following should work for you:

int employeeId = x.nextInt();
x.next(); // skip |
StringBuilder buf = new StringBuilder(x.next());
String nextToken = x.next();
while (nextToken.indexOf('|') < 0) {
    buf.append(" " + nextToken);
    nextToken = x.next();
}
String empName = buf.toString();
int managerId = 0;
String managerIdString = x.next();
if (managerIdString.indexOf('|') < 0) {
    managerId = Integer.parseInt(managerIdString);
    x.next(); // Skip the last |
}

Upvotes: 0

scubasteve623
scubasteve623

Reputation: 647

Places in the file such as Dangermouse not having a managerID may be throwing you off. Try and catch blocks could let the program skip those.

try
{
    int employeeId = x.nextInt();
    String empName = x.next();
    int managerId = x.nextInt();
}
catch (Exception e)
{
    x.nextLine();
    System.out.print(String.ValueOf(index));
}

If the only problem is people not having managers, then this might work better.

int employeeId = x.nextInt();
String empName = x.next();
try
{
    int managerId = x.nextInt();
}

catch(Exception e)
{
    int managerId = -1;  //junk value to let you know this person doesn't have a managerId
}

Also, you may want to consider changing the Id's from int to string. This would really help overcome parsing errors, and wouldn't negatively affect too much. That is, you probably don't plan on ever dividing one managerId by another.

Upvotes: 0

Moshe Tsabari
Moshe Tsabari

Reputation: 372

your data is inconsistency . you are missing "|" so you have this excption when trying to convert "|" to int. I suggesting first build method to check your file and afterword start parsing.

Upvotes: 0

Amitesh Rai
Amitesh Rai

Reputation: 874

The reason it gives you trouble is because when the user enters an integer then hits enter,

two things have just been entered : ->> The integer and a "newline" which is \n.

The method you are calling, nextInt(), only reads in the integer, which leaves the newline in the input stream. But calling nextLine() does read in newlines, which is why you had to call nextLine() before your code would work. You could have also called next(), which would also have read in the newline.

public class DataExtractor {

     //.....
     while (x.hasNext() && index < lineCounter) {        
         String theFile = x.next().replaceAll("[|]", " ");
    
         int employeeId = x.nextInt();
         x.nextLine();  // Added Here to read next value
         String empName = x.next();
         x.nextLine();   // Added Here to read next value
         int managerId = x.nextInt();
                
         System.out.print(theFile);
     }
     //.....    
}

Upvotes: 1

Related Questions