简体   繁体   中英

Java Scanner not working as expected

I am trying to read a file into my java program where the first row in the txt file is an int and everything after is a long. The issue that I am having is every single line of code in the while loop is calling s.nextint() and s.nextLong() (at least when I put a watch on them in Eclipse). I want them only to increment through the text file where I call them.

Firstly, what am I doing wrong because it was my understanding they should only increment when called and not on every line of code, and is there a better way to do this? I was thinking if need be I could just load them all in as a single type to an array and cast later, but this wouldn't be what I consider reasonable. I feel this should be fairly simple but I am overlooking something.

Also lets say there are 10 numbers in the text file and go 1-10. I understand that it is a waste to save a small number as an int but just go with it.

public static long[] readfile()
{
  int row = 1;
  Scanner s = null;
  long[] nums = null;
  try {   
    s = new Scanner(new BufferedReader( new FileReader("text.txt")));   
    while (s.hasNext()) {   
      if(row == 1){
        nums = new long[s.nextInt()];
        row++;
      }
      else {
        nums[row - 2] = s.nextLong();
        row++;
      }
    }
  }
  catch (FileNotFoundException e) {   
    e.printStackTrace();   
  }    
  finally {   
    if (s != null) {   
      s.close();   
    }   
  }   
  return nums;
}

I'd prefer something like this:

do 
{   
  if(row == 1){
    nums = new long[s.nextInt()];
    row++;
  }
  else 
  {
    nums[row] = s.nextLong();
    row++;
  }
}while(s.hasNextLong());

I didn't try to compile or debug it; holler if you need further help. (It assumes there will be an integer atop the file, as you said would be the case. You should probably add code to guard against that not happening.)

You're code is throwing an ArrayIndexOutOfBoundsException . You're trying to use row for two purposes which throws off your array indexing. By the time we get to the else block, row is equal to 2 and you're trying to apply row to an array from 0 - 9 (10 longs for example).

You should trying initializing your array after checking hasNextInt() then get your long numbers after checking hasNextLong()

Code Sample (text.txt has 10 numbers [1234567890]):

public static void main(String[] args) throws Exception {
    long[] longs = readfile();

    if (longs != null) {
        for (long l : longs) {
            System.out.println(l);
        }
    }
}

public static long[] readfile() {
    int row = 0;
    Scanner s = null;
    long[] nums = null;
    try {
        s = new Scanner(new BufferedReader(new FileReader("text.txt")));
        if (s.hasNextInt()) {
            nums = new long[s.nextInt()];
        }
        while (s.hasNextLong()) {
            nums[row] = s.nextLong();
            row++;
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (s != null) {
            s.close();
        }
    }
    return nums;
}

Results:

1234567890
1234567890
1234567890
1234567890
1234567890
1234567890
1234567890
1234567890
1234567890
1234567890

I've generally found that Scanners behave oddly when attempting to read multiple types. I'd create a separate Scanner for each type that you'll be reading.

It seems that the issue i stated was having something to do with an eclipse error. If i just run the code or set a breakpoint after the readfile in the main my code works as expected, but when I stepped through values weren't being assigned right by eclipse i'm guessing. Interesting issue. I would like to see exactly what was causing it. Seems very unlikely but isn't that coding? nothing goes as expected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM