EDIT: Sorry, I'm an idiot. I didn't realize my loop was going for too long for my test documents data, the final product will be 150 lines long, but mine was only 9, causing the error. Sorry for the time wasting, and thanks for the help
So I need to write a program that reads in data from a file, said data is separated by "," which I am using the split command to store in an array. Every 3rd result is in an integer and needs to be parsed as such, but then I encounter an exception. My code specifically..
try {
BufferedReader read = new BufferedReader(new FileReader("temp.txt"));
String file = read.readLine();
String[] store=file.split(",");
for (int i=2; i<150; i=i+3){
int result=Integer.parseInt(store[i]);
if (result>highresult){
highresult = result;
fName = store[i - 1];
sName = store[i - 2];
}
}
read.close();
} catch (IOException e) {
System.out.println("File Read Error");
}
The exceptions is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11
at testing.Testing.main(Testing.java:28)
Java Result: 1
The exception is encountered on the parser inside my for loop, and I cannot for the life of me find the issue. Been staring at it so long I think I'm seeing double. Any ideas whats up with it?
Adding for clearness - the test file itself contains the following data
Name1,Sname1,50,Name2,Sname2,75,Name3,Sname3,100
Testing it with a sysout message shows it collects the data from the array correctly, the issue appears to be when changing every third piece of data, in the array at [2][5][8] (50, 75, 100 in this case) into an integer.
Thank you for your patience, still new to this website.
well I can see 2 problems: either store[i] is not an int, either you want to get a value out of the bounds of the array
just print out the i before parsing and take a look at its value and if it's <150 take a look at its value in the file
Related
Currently i am stuck up with a issue regarding comparing values in a text file. Below is my requirement which is a bit unique is what i can say.
I am getting a text file which is having data in the below format. The lines are a series of numbers of a particular format.
223---other line values
354---other line value
756---other line values
754---other line values
854---other line values
923---other line values
I have to validate that all the lines are starting in this order 2,3,7,8,9. There can be multiple lines in between 2 & 9 starting with 2,3,7,7,8,3,7,7,8,9. It is guranteed that 2 and 9 lines will be the first and last lines in the file. Multiple 7's can appear between 3 & 8.
I came up with the logic below for this comparison but the logic works for only one combination of lines starting with 2,3,7,7,8,9.
When there are multiple occurrences of lines like say 2,3,7,7,8,3,7,7,8,9 it does not work. Can someone please help me with what is wrong here and how i can solve this issue. If there is a better option or any other better way for my requirement please suggest so that i can use it. The volume in the input file is not high and can be almost 10 to 20 thousand.
Set<String> recordTypeOrder = new HashSet<>();
BufferedReader rdr = new BufferedReader(new StringReader("path to my file here"));
for (String line = rdr.readLine(); line != null; line = rdr.readLine()) {
if(line.startsWith("2")){
recordTypeOrder.add("2");
}else if(line.startsWith("3")){
recordTypeOrder.add("3");
}else if(line.startsWith("7")){
recordTypeOrder.add("7");
}else if(line.startsWith("8")){
recordTypeOrder.add("8");
}else if(line.startsWith("9")){
recordTypeOrder.add("9");
}
}
Set<String> orderToCompare = new TreeSet<>(recordTypeOrder);
boolean compare = orderToCompare.equals(actualOrder());
if(!compare){
logger.info("== Processing failed =====");
throw new CustomException("======= Processing failed =======");
}
private static Set<String> actualOrder(){
Set<String> actualOrder= new HashSet<>();
actualOrder.add("2");
actualOrder.add("3");
actualOrder.add("7");
actualOrder.add("8");
actualOrder.add("9");
return actualOrder;
}
Many Thanks
You need to store both order and count of 3,7,7,8. I think treeset won't work. Can you try others data structures like LinkedHashMap. That way you could just store the data you need in LinkedHashMap and then write a custom function to validate it.
Before I start I know this isnt the only way of getting the information from the file I need, since I can use a scanner. However when i've been trying to read it this way the substring seems to be causing problems with this line from the Contract.txt file:07-Jun-2016 1 3 1 N JB847N 900 S Trotter
Which thorws a NormatFormatException "00 " because it is trying to then parse a tab. This is the only line that does this.
public String averageCostOflarge() {
int numberOfBundles = 0;
int total = 0;
try {
BufferedReader reader = new BufferedReader(new FileReader("Contract.txt"));
String line;
while ((line = reader.readLine()) != null) {
if (line.charAt(14) == '3') {
numberOfBundles++;
if(line.charAt(32)=='\t'){
total+=Integer.parseInt(line.substring(28, 32));
}else{
total+=Integer.parseInt(line.substring(28, 31));
}
}
}
reader.close();
return Integer.toString(numberOfBundles);
} catch (FileNotFoundException e) {
return "Error";
} catch (IOException ex) {
Logger.getLogger(ContractSummary.class.getName()).log(Level.SEVERE, null, ex);
return "Error";
}
}
However the it seems to mainly be this part: 1 3 1 N JB847N 900 as this part comes up multiple times in the file.
Contract file: https://pastebin.com/GFG1Um4g
I have removed all the lines that have been causing this problem and the code works just fine.
The section of code needs to check if the third row is set as 3 and then get the cost in the seventh row. The pieces of information are seperated by tabs not spaces and I have tried manually typing the line that is causing the problem to see if it was a formatting error in the file.
Any explanation as to why my code is doing this would be greatly appreciated.
This has nothing to do with a tab; your substring is either "00 " or "00 S", depending on whether the letter following the S is a tab. But parseInt("00 ") throws an exception because of the trailing space.
If you are trying to extract the "900", then your index is off; the first index should be 27 instead of 28. And if you only want to get the part of "900" after the 9, then only ask for 2characters, substring(28,30).
However, depending on the exact character-index seems rather brittle -- sure the date will be a predictable number of characters long, but are the following "1 3 1" each guaranteed to be a single digit, and never longer? Similarly, the "N" and "JB847N" aren't ever longer/shorter?
My first inclination would be to use String.split("\s") to divide your long line into the meaningful chunks.
(Btw, you are looking for the 3rd and 7th "columns" (or, "fields"), not "rows".)
You need to added trim() to remove spaces
if (line.charAt(32) == '\t') {
total += Integer.parseInt(line.substring(28, 32).trim());
} else {
total += Integer.parseInt(line.substring(28, 31).trim());
}
I am having two problems here:
The following block of codes has got me confused. Primarily, I do not know what exactly the code is doing from the basics; I just copied it from a tutorial, and it seems to do what i want it to do. If anyone can explain in bits what it does, it will be really helpful.
The second problem is that I do not know why it throws an ArrayIndexOutOfBounds error, maybe because I do not understand it or otherwise. I really need clarification.
try {
Document searchLink = Jsoup.connect("https://www.google.com.ng/search?dcr=0&source=hp&ei=5-cIWuZ30cCwB7aUhrAN&q=" + URLEncoder.encode(searchValue, encoding))
.userAgent("Mozilla/5.0").get();
String websiteLink = searchLink.getElementsByTag("cite").get(0).text();
//we are setting the value for the action "titles" in the wikipedia API with our own article title
//we use the string method replaceAll() to remove the title of the article from the wikipedia URL that we generated from google
//
String wikiAPItoSearch = "https://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&titles="
+ URLEncoder.encode(websiteLink.replaceAll("https://en.wikipedia.org/wiki/", ""),encoding);
System.out.println(wikiAPItoSearch);
//extraction of textfiles
//from this point till down i cant really grab what is happening
HttpURLConnection httpconn = (HttpURLConnection) new URL(wikiAPItoSearch).openConnection();
httpconn.addRequestProperty("userAgent", "Mozilla/5.0");
BufferedReader bf = new BufferedReader(new InputStreamReader(httpconn.getInputStream()));
//read line by line
String response = bf.lines().collect(Collectors.joining());
bf.close();
///it returns ArrayIndexOutOfBounds here
String result = response.split("\"extract\":\"")[1];
System.out.println(result);
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
I don't think anyone will take the time to explain the code for you. A good opportunity for you to do some debugging.
ArrayIndexOutOfBounds comes from response.split("\"extract\":\"")[1]. There is no guarantee that the String response can be split into at least 2 parts.
Add a check to avoid the error. Instead of...
String result = response.split("\"extract\":\"")[1];
use...
String[] parts = response.split("\"extract\":\"");
String result;
if (parts.length >= 2) {
result = parts[1];
} else {
result = "Error..." + response; // a simple fallback
}
This is how split works:
String input = "one,two,three";
String[] parts = input.split(",");
System.out.println(parts[0]); // prints 'one'
System.out.println(parst[2]); // prints 'three'
So in your case, [1] means the second item in the parts array. "\"extract\":\"" has to appear at least once in the response, otherwise there will be only one item in the parts array, and you will get an error when you try to reach the second item (since it doesn't exist). It all gets extra tricky since .split accepts a regexp string and "\"extract\":\"" contains regexp reserved characters.
OPPS... i realized it was the API that i was using that caused the error, the API i got from wikimedia does not use /extract /as a delimetre , so i checked other stack overflow articles for a more cleaner API especially a one that uses /extract/ as a delimetre for the API response.
this is the new API i got :
https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=
this was the former one that causes the error:
https://en.wikipedia.org/w/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=
i think the error was caused by my inability to understand the process in-dept.. thanks for the responses.
I am working on a project which involves making a "worker" in java which receives instructions from an input string. In the input string normally should be first four numbers and then afterwards a number and a letter right after being N,S,W, or E. The first 2 numbers in the list are used to determine the size of the area this worker can walk. the next two numbers are the starting point for the worker. The number with the letter determines what direction the worker walks and how many paces. The problem I am having is I don't understand how to get the first four digits out of the string and separate them into what they each should be.
import java.util.*;
import java.io.*;
public class Worker {
private int height;
public void readInstructions(String inputFileName, String outputFileName) throws InvalidWorkerInstructionException{
try{
Scanner in = new Scanner(inputFileName);
PrintWriter wrt;
wrt = new PrintWriter(outputFileName);
if(inputFileName.startsWith("i")){
System.out.println("Input file not found.");
//wrt.println("Input file not found.");
}
while(in.hasNext()){
String s = in.nextLine();
if(Integer.parseInt(s)<= 9){
}
}
}catch(InvalidWorkerInstructionException e){
}catch(FileNotFoundException e){
}
While I would love to ask for a straight up answer, this is a project so I would prefer nobody gives me a fixed code. Please if you can give me advice for what I am doing wrong and where I should be going to solve the problem.
Ok I realized one other thing because I tried the advice given. So I am receiving a string that gives me the name of an input txt. Inside that input txt is the numbers and directions. How can i access this text file? Also how do I determine if it can be opened?
Okay, so you already know how to read the file using a Scanner. All you need to do next is split the String and extract the first four inputs out of it.
Here is the code snippet:
String s = in.nextLine();
int i = 0, digits[] = new int[4];
for(String inp : s.splits(" ")) {
if(i == 4) break;
digits[i++] = Integer.parseInt(inp);
}
Note: I'm assuming that the inputs in your file is space separated. If not then you can replace the space in the split() with the correct delimiter.
If input format is fixed than you can use substring method to get different parts of string. Refer documentation for more detail:
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int,%20int)
Example code:
String s = "12345E";
s.substring(0, 2); /* 12 */
s.substring(2, 4); /* 34 */
s.substring(4, 5); /* 5 */
s.substring(5, 6); /* E */
You can use the method .getChars() to accomplish this. Here is what the javadoc says about this method:
public void getChars(int srcBegin,
int srcEnd,
char[] dst,
int dstBegin)
Copies characters from this string into the destination character array.
The first character to be copied is at index srcBegin; the last character to be copied is at index srcEnd-1 (thus the total number of characters to be copied is srcEnd-srcBegin). The characters are copied into the subarray of dst starting at index dstBegin and ending at index:
dstbegin + (srcEnd-srcBegin) - 1
Parameters:
srcBegin - index of the first character in the string to copy.
srcEnd - index after the last character in the string to copy.
dst - the destination array.
dstBegin - the start offset in the destination array.
Throws:
IndexOutOfBoundsException - If any of the following is true:
srcBegin is negative.
srcBegin is greater than srcEnd
srcEnd is greater than the length of this string
dstBegin is negative
dstBegin+(srcEnd-srcBegin) is larger than dst.lengt....
Here is what you could do...
You read in the string - grab its length (You want to make sure that it has all the chars you need)
Read in to a separate array discarding any extraneous chars that are not needed for this functionality..
You can make your own pseudo code to work out the problem once the string is split into an array. Very easy to work with since you know what each location of the array is supposed to do.
This is not a hard problem to solve at all..
Good luck on your project.
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)
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.
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!
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());
}
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.