0

My code is designed to read the contents of a text file and check if the contents are entered in a format that is as follows:

john : martin : 2 : 1

and if that format is followed then it will output it in the format:

john  [2] | martin [1]

or else it will be counted as an invalid result and the total numbers will not be added to it whereas if the results are in the format then they will get added to the total so with the example it would display the number of vaild results as 1, invalid as 0 and total number as 3.

My question is that my code doesn't work properly as I get this error:

Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at reader.main(reader.java:33)

So how would I go about fixing this and reading and displaying the data in thee way that I want? Thanks in advance.

import java.io.FileReader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Locale;
import java.util.Scanner;


public class reader {

    /**
     * @param args
     * @throws FileNotFoundException 
     * @throws FileNotFoundException 
     * @throws FileNotFoundException when the file cannot be loaded 
     */

    public static void main(String[] args) throws FileNotFoundException {

        String hteam;
        String ateam;
        int hscore;
        int ascore;

        Scanner s = new Scanner(new BufferedReader(new FileReader("results2.txt"))).useDelimiter(":");
        // create a scanner which scans from a file and splits at each colon

        while ( s.hasNext() ) { 
            hteam = s.next();       // read the home team from the file
            ateam = s.next();       // read the away team from the file
            hscore = s.nextInt();       //read the home team score from the file
            ascore = s.nextInt();       //read the away team score from the file

            System.out.print(hteam);    // output the line of text to the console
            System.out.print(hscore);
            System.out.print(ateam);
            System.out.println(ascore);
        }
        System.out.println("\nEOF");    // Output and End Of File message.
    }
}
irrelephant
  • 4,091
  • 2
  • 25
  • 41
fs fd
  • 3
  • 3

2 Answers2

0

You're looking for s.next() instead of s.nextLine().

hteam = s.nextLine() reads the entire line "john : martin : 2 : 1", leaving nothing left for ateam.

Edit:

As you've said this still isn't working, I'd guess that you have an extra newline at the end of your input file, which is causing s.hasNext() to evaluate to true. This would cause the Scanner to trip up when it's getting the next input line.

Try Scanner s = new Scanner(System.in).useDelimiter("\\s*:\\s*|\\s*\\n\\s*"); to read multiple lines.

See implementation: http://ideone.com/yfiR2S

To verify that a line is in the correct format, I'd (with inspiration from osoblanco's answer) check that there are 4 words and that the last two are integers:

public static boolean verifyFormat(String[] words) {
    // see endnote for isInteger()
    return words.length == 4 && /*isInteger(words[2]) && isInteger(words[3])*/;
}

public static void main(String[] args) throws FileNotFoundException {

    String hteam;
    String ateam;
    int hscore;
    int ascore;
    Scanner s = new Scanner(new BufferedReader(
            new FileReader("results2.txt"))).useDelimiter("\\s*:\\s*|\\s*\\n\\s*");

    while (s.hasNext()) {
        String line = s.nextLine();
        String[] words = line.split("\\s*:\\s*");

        if(verifyFormat(words)) {
            hteam = words[0];       // read the home team
            ateam = words[1];       // read the away team
            hscore = Integer.parseInt(words[2]);       //read the home team score
            ascore = Integer.parseInt(words[3]);       //read the away team score

            System.out.print(hteam);    // output the line of text to the console
            System.out.print(hscore);
            System.out.print(ateam);
            System.out.println(ascore);
        }
    }

    System.out.println("EOF");
}

isInteger() can be found here.

Community
  • 1
  • 1
irrelephant
  • 4,091
  • 2
  • 25
  • 41
  • Replacing s.nextline() with s.next() just results in the same errors being displayed. – fs fd Nov 07 '14 at 19:44
  • Strange, it seems to work here: http://ideone.com/TQD2g6. Perhaps your input file has a newline at the end, and so `s.hasNext()` is evaluating to true. – irrelephant Nov 07 '14 at 19:56
  • See the edit in the delimiter. I ran it locally and it worked. – irrelephant Nov 07 '14 at 20:28
  • Yeah, this fixed the issues with it not reading the correct results past the first one thanks but how would I get it to read a result in an invalid format and just record it as invalid but carry on running and recording the results that are in the correct format? – fs fd Nov 07 '14 at 20:34
  • I'd do mostly what @osoblanco suggests, although you can just use a Scanner to `readLine()`. – irrelephant Nov 07 '14 at 20:37
  • Would that involve rewriting the entire reader or is there someway to implement it to make it so that it will work with the current setup? Also how would I go about doing the validation and trimming? Sorry about the stupid beginner questions. – fs fd Nov 07 '14 at 20:41
  • http://ideone.com/dXxnMP is my code & my question is what do I modify about the top and how do i make the number of invalid and valid results display as it says that they are static integers and as such can't reference an invalid integer. – fs fd Nov 07 '14 at 21:46
  • Just make `isInteger()`, `validresults`, and `invalidresults` static. – irrelephant Nov 07 '14 at 22:45
  • How would I make it so that the reader will read the string so that if one of the strings has just whitespace for the team name then it will get counted as an invalid result? – fs fd Nov 09 '14 at 17:50
  • In `verifyFormat`, you would check that `for(String w : words) if("".equals(w)) return false;` – irrelephant Nov 09 '14 at 22:36
0

I think scanning isn't quite what you want here. I would just use a BufferedReader and do ReadLine to handle 1 line each time through the for loop.

Then verify each line by the following:

1) String.split(":") and verify 4 pieces.

String [] linePieces = nextLine.split(":");
if(linePieces.length!=4)
{
    //mark invalid, continue loop
}

2) Trim each piece

for(int i =0; i<4; i++)
    linePieces[i] = linePieces[i].trim();

3) Verify piece 3 and piece 4 are numbers, Integer.parseInt with try/catch. In the catch block, count that the line is invalid.

try
{
    name1=linePieces[0];
    name2=linePieces[1];
    score1=Integer.parseInt(linePieces[2]);
    score2=Integer.parseInt(linePieces[3]);
    //count as success and do logic
}catch(NumberFormatException e){
   //invalid line
}
osoblanco
  • 468
  • 2
  • 10
  • How would I do this? I know how to set up a BufferedReader and the String.split but the verifying part I'm not sure about. – fs fd Nov 07 '14 at 19:57