views:

181

answers:

4
Scanner s = null;
    try {
        s = new Scanner(new BufferedReader(new FileReader("rates.txt")));
            for (int i=0; i<9; i++){
                while(s.hasNext()){rates[i] = s.next();}
                System.out.println(rates[i]);
            }
    }catch (IOException e){
        System.out.println(e);
    }
    finally {
        if (s != null) {
            s.close();
        }
    }

When I run this code, it reads the last chunk of characters in my txt file, places them in rates[0], sticks null in 1-9. I'm not sure why it's reading the end of my file first. The contents of the txt are below..

USD 1.34

EUR 1.00

JPY 126.28

GBP 0.88

INR 60.20

It reads the 60.20, which is all it is recording in the array. Any help would be appreciated. I guess I could give you the results of running this code:

run:
60.20
null
null
null
null
null
null
null
null
BUILD SUCCESSFUL (total time: 0 seconds)
+2  A: 
while(s.hasNext()){rates[i] = s.next();}

In plain english, this says: While there are tokens left, put the next token into rates[i].

So it will put the first token into rates[i], then the next token into rates[i], then the next token into rates[i], ..., and finally the last token into rates[i]. Since i is not modified, all the values are written into the same element of the array, overwriting the previously read values.

meriton
/facepalm Thank you.
DeliriumTremens
+1 indeed, good find! @deliriumtremens don't forget to accept his answer :-)
Péter Török
A: 

I think the problem is that line 5, which contains your while loop, reads the entire file input. So you read your entire file on the first for loop iteration where i = 0; The next time your for loop there is nothing left to read.

You probably want something like this instead:

List rates = new ArrayList();
while (s.hasNext()) {
      rates.add(s.next());
}
gregcase
+1  A: 

I recommend:

  • Using List instead of array
    • More flexible, much easier to work with, takes advantage of Java Collections Framework, etc
  • Not storing the currency symbol and the numeric exchange rate all in one mixed bag
    • ...but using a class to encapsulate the pair
  • Using Scanner.nextDouble() to read the numeric exchange rate (which presumably you'll want to convert to double anyway)

So, something like this:

List<ExchangeRate> allRates = new ArrayList<ExchangeRate>();
while (sc.hasNext()) {
    String symbol = sc.next();
    double rate = sc.nextDouble();
    allRates.add(new ExchangeRate(symbol, rate));
}

Note how:

  • You no longer need to know how many elements to allocate in an array
  • The symbol and the rate aren't all thrown into one mixed bag
  • List.add means no counter that you need to keep track of and manage
    • i.e. the bug in your original question!
polygenelubricants
A: 

One other potential problem: FileReader uses the platform default encoding. This can be appropriate to process user-supplied files, but if the files are part of the application, they can get corrupted when the application is run on a system with an incompatible default encoding (and no, using only ASCII characters does not protect you completely against this).

To avoid the problem, use new InputStreamReader(new FileInputStream(filename), encoding) instead - and realize that you actually have to pick an encoding for your file.

Michael Borgwardt