Taking in a list of strings and converting them to a float and storing the values. I get this error when hitting the second value I want to store. Below is the code and the text file I'm reading from:
public static void readCities() {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("C:/Users/Luke/workspace/Traveling Sales Person/Destinations/11PointDFSBFS.tsp"));
String line;
while ((line = br.readLine()) != null) {
if (sb.length() > 0) {
sb.append("\n");
}
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
String contents = sb.toString();
String[] parts = contents.split("NODE_COORD_SECTION");//splits into locations
String[] locations = parts[1].split(" ");
int counter = 0;
for (int i = 1; i < locations.length; i++) {
cities[counter] = new City(Float.parseFloat(locations[i+1]), Float.parseFloat(locations[i+2]));
counter++;
}
}
Code error:
Exception in thread "main" java.lang.NumberFormatException: For input string: "63.860370
2
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseFloat(FloatingDecimal.java:122)
at java.lang.Float.parseFloat(Float.java:451)
at TSP.readCities(TSP.java:132)
at TSP.main(TSP.java:28)
As all the commenters already said: Without the actual data it's more or less guessing, what is the problem, but with your code and the error-message some things can be said already, what you should do independly:
You read in all the lines and put them into a StringBuilder including a new line-break. Later on you do splits, but you never remove this line-break, so it is going to end up in the data you try to parse as float. This will lead to a parsing error, because spaces and other whitespaces are not removed. The easiest way to do this without changing too much in your code is by trimming the values:
cities[counter] = new City(Float.parseFloat(locations[i+1].trim()), Float.parseFloat(locations[i+2],trim()));
BTW: What's the reason for creating a new variable counter that is essentially i-1 and using i+1 and i+2 later on? Makes reading your code a bit harder, because you expect some additional logic where entries are skipped which isn't there.
According to the error-message the problem is a leading quotation mark and a newline. You can't say if that error occurred for the first or the second of the two values that are parsed and without the original line(s) of the input file it's hard to say, what is going on, but maybe I gave you enough hints to allow you to progress with your code.
If not we need more informations, especially the line(s) that produce this error, so analysing your code becomes possible.
Related
I am learning Java. I believe I have an issue understanding how BufferedReader processes "\n" or "" strings (newline and empty strings).
If I run the following it will fail if I put either of those strings into the String array.
String [] strings = {"55", "23", ""};
int total = 0;
for (String str : strings)
{
if (str != null) {
total += Integer.valueOf(str);
}
}
System.out.println(total);
This is fine, and makes sense to me. What does not make sense to me is when I run this code in reading in a file.
BufferedReader reader = null;
int total = 0;
try {
reader = new BufferedReader(new FileReader("E:\\Testing\\Numbers.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
total += Integer.valueOf(line);
System.out.println("Total: " + total);
} catch(Exception e){
System.out.println(e.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
using a text file that has the following:
5
2
3
It runs without errors. If I add a single blank line in the same file (), it fails with the message For input string: ""
I added an isNumeric function to solve the issue, but I don't understand why the BufferedReader will work when I run the code without any empty lines, even though it does not like the "\n" or "" strings. I looked up valueOf() in the javadocs and I did not see anything that helped me.
Here is my final code that uses the isNumeric function and shows how it sees both the "\n" and "" strings as non-numeric.
BufferedReader reader = null;
int total = 0;
try {
reader = new BufferedReader(new FileReader("E:\\Testing\\Numbers.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
if (isNumeric(line))
{
System.out.println(line);
total += Integer.valueOf(line);
}
System.out.println("Skipping a non numeric value");
}
System.out.println("Total: " + total);
} catch(Exception e){
System.out.println(e.getMessage());
} finally {
try {
if (reader != null)
reader.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
public static boolean isNumeric(String str)
{
try
{
int d = Integer.parseInt(str);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
6
Skipping a non numeric value
1
Skipping a non numeric value
Skipping a non numeric value
2
Skipping a non numeric value
62
Skipping a non numeric value
23
Skipping a non numeric value
Total: 94
Finally I did see this article on the site, and it is close, but I still could not figure it out.
When using a BufferedReader, the readLine() method will consume any "new line like" characters automatically.
So, in essence, your initial file was
5\n
...
And the \n is simply removed before giving the string to your code. If the line is just \n; then you get "". An easy way to check for that is line.isEmpty().
Regarding: I don't understand why the BufferedReader will work when I run the code without any empty lines; well I don't understand that question. If your code only reads lines with numbers, it doesn't matter that you have code sitting there that could deal with empty lines; or lines containing "invalid" number text.
I have to make an EPG app using java, but I am kind of new in programming and it's due tomorrow and it's still not working properly.
I have a question about a small part: I have to read the programs from a text file. Each line contains multiple things, the channel, the title of the program, a subtitle, a category, etcetera.
I have to make sure that I can read the separate parts of each line, but it's not really working, it's only printing the parts from the first line.
I am trying, but I can't find why it's not printing all the parts from all the lines in stead of printing only the parts from the first line. Here's the code:
BufferedReader reader = new BufferedReader(newFileReader(filepath));
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
}
String[] parts = line.split("\\|", -1);
for(int i = 0; i < parts.length; i++) {
System.out.println(parts[i]);
}
reader.close();
Does anybody know how to get all the lines in stead of only the first?
Thank you!
readLine() only reads one line, so you need to loop it, as you said.
BUT with reading to the String inside of the while loop you always overwrite that String.
You would need to declare the String above the while loop that you can access it from outside, too.
BTW, it seems that your braces for the if don't match.
Anyway, I'd fill the information into an ArrayList, look below:
List<String> list = new ArrayList<>();
String content;
// readLine() and close() may throw errors, so they require you to catch it…
try {
while ((content = reader.readLine()) != null) {
list.add(content);
}
reader.close();
} catch (IOException e) {
// This just prints the error log to the console if something goes wrong
e.printStackTrace();
}
// Now proceed with your list, e.g. retrieve first item and split
String[] parts = list.get(0).split("\\|", -1);
// You can simplify the for loop like this,
// you call this for each:
for (String s : parts) {
System.out.println(s);
}
Use apache commons lib
File file = new File("test.txt");
List<String> lines = FileUtils.readLines(file);
As ArrayList is Dynamic,try,
private static List<String> readFile(String filepath) {
String line = null;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader(filepath));
while((line = reader.readLine()) != null){
list.add(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
In my journey to complete this program I've run into a little hitch with one of my methods. The method I am writing reads a certain .txt file and creates a HashMap and sets every word found as a Key and the amount of time it appears is its Value. I have managed to figure this out for another method, but this time, the .txt file the method is reading is in a weird format. Specifically:
more 2
morning's 1
most 3
mostly 1
mythology. 1
native 1
nearly 2
northern 1
occupying 1
of 29
off 1
And so on.
Right now, the method is returning only one line in the file.
Here is my code for the method:
public static HashMap<String,Integer> readVocabulary(String fileName) {
// Declare the HashMap to be returned
HashMap<String, Integer> wordCount = new HashMap();
String toRead = fileName;
try {
FileReader reader = new FileReader(toRead);
BufferedReader br = new BufferedReader(reader);
// The BufferedReader reads the lines
String line = br.readLine();
// Split the line into a String array to loop through
String[] words = line.split(" ");
// for loop goes through every word
for (int i = 0; i < words.length; i++) {
// Case if the HashMap already contains the key.
// If so, just increments the value.
if (wordCount.containsKey(words[i])) {
int n = wordCount.get(words[i]);
wordCount.put(words[i], ++n);
}
// Otherwise, puts the word into the HashMap
else {
wordCount.put(words[i], 1);
}
}
br.close();
}
// Catching the file not found error
// and any other errors
catch (FileNotFoundException fnfe) {
System.err.println("File not found.");
}
catch (Exception e) {
System.err.print(e);
}
return wordCount;
}
The issue is that I'm not sure how to get the method to ignore the 2's and 1's and 29's of the .txt file. I attempted making an 'else if' statement to catch all of these cases but there are too many. Is there a way for me to catch all the ints from say, 1-100, and exlude them from being Keys in the HashMap? I've searched online but have turned up something.
Thank you for any help you can give!
How about just doing wordCount.put(words[0],1) into wordcount for every line, after you've done the split. If the pattern is always "word number", you only need the first item from the split array.
Update after some back and forth
public static HashMap<String,Integer> readVocabulary(String toRead)
{
// Declare the HashMap to be returned
HashMap<String, Integer> wordCount = new HashMap<String, Integer>();
String line = null;
String[] words = null;
int lineNumber = 0;
FileReader reader = null;
BufferedReader br = null;
try {
reader = new FileReader(toRead);
br = new BufferedReader(reader);
// Split the line into a String array to loop through
while ((line = br.readLine()) != null) {
lineNumber++;
words = line.split(" ");
if (words.length == 2) {
if (wordCount.containsKey(words[0]))
{
int n = wordCount.get(words[0]);
wordCount.put(words[0], ++n);
}
// Otherwise, puts the word into the HashMap
else
{
boolean word2IsInteger = true;
try
{
Integer.parseInt(words[1]);
}
catch(NumberFormatException nfe)
{
word2IsInteger = false;
}
if (word2IsInteger) {
wordCount.put(words[0], Integer.parseInt(words[1]));
}
}
}
}
br.close();
br = null;
reader.close();
reader = null;
}
// Catching the file not found error
// and any other errors
catch (FileNotFoundException fnfe) {
System.err.println("File not found.");
}
catch (Exception e) {
System.err.print(e);
}
return wordCount;
}
To check if a String contains a only digits use String´s matches() method, e.g.
if (!words[i].matches("^\\d+$")){
// NOT a String containing only digits
}
This wont require checking exceptions and it doesnt matter if the number wouldnt fit inside an Integer.
Option 1: Ignore numbers separated by whitespace
Use Integer.parseInt() or Double.parseInt() and catch the exception.
// for loop goes through every word
for (int i = 0; i < words.length; i++) {
try {
int wordAsInt = Integer.parseInt(words[i]);
} catch(NumberFormatException e) {
// Case if the HashMap already contains the key.
// If so, just increments the value.
if (wordCount.containsKey(words[i])) {
int n = wordCount.get(words[i]);
wordCount.put(words[i], ++n);
}
// Otherwise, puts the word into the HashMap
else {
wordCount.put(words[i], 1);
}
}
}
There is a Double.parseDouble(String) method, which you could use in place of Integer.parseInt(String) above if you wanted to eliminate all numbers, not just integers.
Option 2: Ignore numbers everywhere
Another option is to parse your input one character at a time and ignore any character that isn't a letter. When you scan whitespace, then you could add the word generated by the characters just scanned in to your HashMap. Unlike the methods mentioned above, scanning by character would allow you to ignore numbers even if they appear immediately next to other characters.
if i have this line in a file: 2 18 4 3
and i want to read it as individual integers, how could i?
i'm using bufferreader:
BufferedReader(new FileReader("mp1.data.txt"));
i have tried to use:
BufferedReader(new RandomAccessFile("mp1.data.txt"));
so i can use the method
.readCahr();
but i got an error
if i use
int w = in.read();
it will read the ASCII, and i want it as it is(in dec.)
i was thinking to read it as a string first, but then could i separate each number?
also i was thinking to let each number in a line, but the file i have is long with numbers
Consider using a Scanner:
Scanner scan = new Scanner(new File("mp1.data.txt"));
You can then use scan.nextInt() (which returns an int, not a String) so long as scan.hasNextInt().
No need for that ugly splitting and parsing :)
However, note that this approach will continue reading integers past the first line (if that's not what you want, you should probably follow the suggestions outlined in the other answers for reading and handling only a single line).
Furthermore, hasNextInt() will return false as soon as a non-integer is encountered in the file. If you require a way to detect and handle invalid data, you should again consider the other answers.
It's important to approach larger problems in software engineering by breaking them into smaller ones. In this case, you've got three tasks:
Read a line from the file
Break it into individual parts (still strings)
Convert each part into an integer
Java makes each of these simple:
Use BufferedReader.readLine() to read the line as a string first
It looks like the splitting is as simple as splitting by a space with String.split():
String[] bits = line.split(" ");
If that's not good enough, you can use a more complicated regular expression in the split call.
Parse each part using Integer.parseInt().
Another option for the splitting part is to use the Splitter class from Guava. Personally I prefer that, but it's a matter of taste.
You can split() the String and then use the Integer.parseInt() method in order to convert all the elements to Integer objects.
try {
BufferedReader br = new BufferedReader(new FileReader("mp1.data.txt"));
String line = null;
while ((line = br.readLine()) != null) {
String[] split = line.split("\\s");
for (String element : split) {
Integer parsedInteger = Integer.parseInt(element);
System.out.println(parsedInteger);
}
}
}
catch (IOException e) {
System.err.println("Error: " + e);
}
Once you read the line using BufferedReader, you can use String.split(regex) method to split the string by space ("\\s").
for(String s : "2 18 4 3".split("\\s")) {
int i = Integer.parseInt(s);
System.out.println(i);
}
If you use Java 7+, you can use this utility method:
List<String> lines = Files.readAllLines(file, Charset.forName("UTF-8"));
for (String line: lines) {
String[] numbers = line.split("\\s+");
int firstNumber = Integer.parseInt(numbers[0]);
//etc
}
Try this;
try{
// Open the file that is the first
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
//split line by whitespace
String[] ints = strLine.split(" ");
int[] integers = new int[ints.length];
// to convert from string to integers - Integer.parseInt ("123")
for ( int i = 0; i < ints.length; i++) {
integers[i] = Integer.parseInt(ints[i]);
}
// now do what you want with your integer
// ...
}
in.close();
} catch (Exception e) {//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
I'm reading from a file that has the following format:
name : symptoms : causes : treatments : rate : prognosis
There are a total of 21 entries but when I try to read from the file and use .split(":");, the output changes each time but is always along the lines of: [Ljava.lang.String;#614951ff. I'm guessing it's the pointer or memory address but I want the String value. I'm not getting any exceptions though so I'm not sure where I've gone wrong. The purpose of the method is to read the file and split into an array using the delimiter for the given file row selected.
public String[] readCancer(int row) {
cancers = new String[22];
FileInputStream fis;
InputStreamReader isr;
BufferedReader br = null;
String eachCancer;
String[] splitCancer = null;
int j = 0;
try {
fis = new FileInputStream(myData);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
input = new Scanner(br);
while(input.hasNext() && j < 23) {
cancers[j++] = input.nextLine();
}
eachCancer = cancers[row].toString();
splitCancer = eachCancer.split(":");
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with file input");
} finally {
try {
if(br != null) {
br.close();
}
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem closing the file");
}
}
return splitCancer;
}
To print the contents of array :
1) System.out.println(Arrays.deepToString(splitCancer));
2) System.out.println(Arrays.toString(splitCancer));
3) System.out.println(Arrays.asList(splitCancer));
If you want to display the string array, you should use:
System.out.println(Arrays.toString(splitCancer));
Because when you print splitCancer you'll get the address of the array and not the content of it.
Of course you can print the content in other ways:
for(String str : splitCancer) {
System.out.println(str);
}
Currently I have the following:
public String[] readCancer() {
cancers = new String[22];
split = new String[22];
FileInputStream fis;
InputStreamReader isr;
BufferedReader br = null;
String eachCancer;
int j = 0;
try {
fis = new FileInputStream(myData);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
input = new Scanner(br);
while(input.hasNext() && j < 23) {
cancers[j] = input.nextLine().toString();
//cancers[j] = input.nextLine();
split[j] = cancers[j].split(":");
//split[j] = "blah"; this line works
j++;
}
System.out.println(Arrays.toString(split));
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with file input");
} finally {
try {
if(br != null) {
br.close();
}
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem closing the file");
}
}
return split;
//return split[j]; does not work
}
In my while loop, I keep getting compile errors saying it requires a String but found Stirng[] for split. When I try something simpler, such as split[j] = "blah";, there are no compile errors. I can return cancers perfectly but I need to split by the : delimiter and that seems to be something I cant get my head around. When I try return split[j], then I get another compile error saying it requires a String[] but found String. I've been at this for more than an hour, read through examples in my textbook and tutorials online for using split but it still isn't working. This is the only part of my program that I'm not sure how to do.
I tried pasting the entire file but it came a horrid block of text, so here are 2 lines from it. Each line has the same format but differing lengths:
The general format of the file is name : symptoms : causes : treatment : rate : prognosis
The rate is a String since it is unknown for some diseases and when it is known, the rate is not always out of 250,000. Sometimes it is out of 1,000,000 or 100,000, etc... .
acute promyelocytic leukemia : easy bruising, rapid internal bleeding, fatigue, anemia, frequent fever, infection, blood clots : PML and RARA genes : Medications, chemotherapy : 1 in 250,000 : Good
familial cylindromatosis : numerous skin tumours, ulcers, infection, impaired eyesight, hearing, smell, balance : CYLD gene : Surgery, chemotherapy : Unknown : Unknown
My most recent code attempt is at Unusual output from using split()
The 2 arrays of cancers and split are private String[] as field variables declared outside any of the methods. The variable myData is a private File also declared as a field variable outside any of the methods. I have checked and already verified the file path is correct.
The main method that calls the method:
public static void main(String[] args) {
CancerGUI _gui = new CancerGUI();
String[] resultCancer;
resultCancer = _gui.readCancer();
//System.out.println(resultCancer);
System.out.println(Arrays.toString(resultCancer));
}
I am only calling it in the main method to test whether it correctly returns the String[]. Once it does, then I will call it in a different method that adds the data to a GUI (this part I am reasonably confident I know how to do and have examples from my instructor and textbook to follow).