Here's the .txt file i'm trying to read from
20,Dan,09/05/1990,3,Here
5,Danezo,04/09/1990,99,There
And here's how I'm doing it.. Whenever the .txt file has only one line, it seems to be reading from file fine. Whenever more than one line is being read, I get this error
Exception in thread "main" java.lang.NumberFormatException: For input string: "Danezo"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at AttackMonitor.readFromFile(AttackMonitor.java:137)
at AttackMonitor.monitor(AttackMonitor.java:57)
at MonsterAttackDriver.main(MonsterAttackDriver.java:14)
Java Result: 1
Here's the readfromfile code.
private void readFromFile() throws FileNotFoundException, IOException
{
monsterAttacks.clear();
Scanner read = new Scanner(new File("Attacks.txt"));
read.useDelimiter(",");
String fullDateIn = "";
int attackIdIn = 0;
int attackVictimsIn = 0;
String monsterNameIn= "";
String attackLocationIn= "";
while (read.hasNext())
{
attackIdIn = Integer.parseInt(read.next());
monsterNameIn = read.next();
fullDateIn = read.next();
attackVictimsIn = Integer.parseInt(read.next());
attackLocationIn = read.next();
monsterAttacks.add(new MonsterAttack(fullDateIn, attackIdIn, attackVictimsIn, monsterNameIn, attackLocationIn));
}
read.close();
}
What is happening is that at the end of each line there is a newline character, which is currently not a delimiter. So your code is attempting to read it as the first integer of the next line, which it is not. This is causing the parse exception.
To remedy this, you can try adding newline to the list of delimiters for which to scan:
Scanner read = new Scanner(new File("Attacks.txt"));
read.useDelimiter("[,\r\n]+"); // use just \n on Linux
An alternative to this would be to just read in each entire line from the file and split on comma:
String[] parts = read.nextLine().split(",");
attackIdIn = Integer.parseInt(parts[0]);
monsterNameIn = parts[1];
fullDateIn = parts[2];
attackVictimsIn = Integer.parseInt(parts[3]);
attackLocationIn = parts[4];
You can use the Biegeleisen suggestion. Or else you can do as follows.
In your while loop you are using hasNext as condition. Instead of that you can use while (read.hasNextLine()) and get the nextLine inside the loop and then split it by your delimiter and do the processing. That would be a more appropriate approach.
e.g
while (read.hasNextLine()) {
String[] values = scanner.nextLine().split(".");
// do your rest of the logic
}
Put the while loop content in a try catch, and catch for NumberFormatException. So whenever it falls to catch code, you can understand you tried to convert a string to int.
Could help more if your business is explained.
attackLocationIn = read.next(); This value takes as "Here\n 5" because there is no comma between Here and 5 and it has new line character.
so 2nd iteration attackIdIn = Integer.parseInt(read.next()); here read.next() value is "Danezo" it is String and you are trying parse to Integer. That's why you are getting this exception.
What I suggest is use BufferReader to read line by line and split each line with comma. It will be fast also.
Or another solution Add comma at end of each line and use read.next().trim() in your code. That's it it will work with minimal changes to your current code.
Related
I want to read from a txt file which contains just numbers. Such file is in UTF-8, and the numbers are separated only by new lines (no spaces or any other things) just that. Whenever i call Integer.valueOf(myString), i get the exception.
This exception is really strange, because if i create a predefined string, such as "56\n", and use .trim(), it works perfectly. But in my code, not only that is not the case, but the exception texts says that what it couldn't convert was "54856". I have tried to introduce a new line there, and then the error text says it couldn't convert "54856
"
With that out of the question, what am I missing?
File ficheroEntrada = new File("C:\\in.txt");
FileReader entrada =new FileReader(ficheroEntrada);
BufferedReader input = new BufferedReader(entrada);
String s = input.readLine();
System.out.println(s);
Integer in;
in = Integer.valueOf(s.trim());
System.out.println(in);
The exception text reads as follows:
Exception in thread "main" java.lang.NumberFormatException: For input string: "54856"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:658)
at java.base/java.lang.Integer.valueOf(Integer.java:989)
at Quicksort.main(Quicksort.java:170)
The file in.txt consists of:
54856
896
54
53
2
5634
Well, aparently it had to do with Windows and those \r that it uses... I just tried executing it on a Linux VM and it worked. Thanks to everyone that answered!!
Try reading the file with Scanner class has use it's hasNextInt() method to identify what you are reading is Integer or not. This will help you find out what String/character is causing the issue
public static void main(String[] args) throws Exception {
File ficheroEntrada = new File(
"C:\\in.txt");
Scanner scan = new Scanner(ficheroEntrada);
while (scan.hasNext()) {
if (scan.hasNextInt()) {
System.out.println("found integer" + scan.nextInt());
} else {
System.out.println("not integer" + scan.next());
}
}
}
If you want to ensure parsability of a string, you could use a Pattern and Regex that.
Pattern intPattern = Pattern.compile("\\-?\\d+");
Matcher matcher = intPattern.matcher(input);
if (matcher.find()) {
int value = Integer.parseInt(matcher.group(0));
// ... do something with the result.
} else {
// ... handle unparsable line.
}
This pattern allows any numbers and optionally a minus before (without whitespace). It should definetly parse, unless it is too long. I don't know how it handles that, but your example seems to contain mostly short integers, so this should not matter.
Most probably you have a leading/trailing whitespaces in your input, something like:
String s = " 5436";
System.out.println(s);
Integer in;
in = Integer.valueOf(s.trim());
System.out.println(in);
Use trim() on string to get rid of it.
UPDATE 2:
If your file contains something like:
54856\n
896
54\n
53
2\n
5634
then use following code for it:
....your code
FileReader enter = new FileReader(file);
BufferedReader input = new BufferedReader(enter);
String currentLine;
while ((currentLine = input.readLine()) != null) {
Integer in;
//get rid of non-numbers
in = Integer.valueOf(currentLine.replaceAll("\\D+",""));
System.out.println(in);
...your code
Basically I've got an assignment which reads multiple lines from a .txt file.
There are 4 values in the text file per line and each value is separated by 2 spaces.
There are about 10 lines of data in the file.
After taking the input from the file the program then puts it onto a Database. The database connection functionality works fine.
My issue now is with reading from the file using a BufferedReader.
The issue is that if I uncomment any 1 of the 3 lines at the bottom the BufferedReader reads every other line. And if I don't use them then there's an exception as the next input is of type String.
I have contemplated using a Scanner with the .hasNextLine() method.
Any thoughts on what could be the problem and how to fix it?
Thanks.
File file = new File(FILE_INPUT_NAME);
FileReader fr = new FileReader(file);
BufferedReader readFile = new BufferedReader(fr);
String line = null;
while ((line = readFile.readLine()) != null) {
String[] split = line.split(" ", 4);
String id = split[0];
nameFromFile = split[1];
String year = split[2];
String mark = split[3];
idFromFile = Integer.parseInt(id);
yearOfStudyFromFile = Integer.parseInt(year);
markFromFile = Integer.parseInt(mark);
//line = readFile.readLine();
//readFile.readLine();
//System.out.println(readFile.readLine());
}
Edit: There was an error in the formatting of the .txt file. a missing value.
But now I get an ArrayOutOfBoundsException.
Edit edit: Another error in the .txt file! Turns out there was a single space instead of a double. It seems to be working now. But any advice on how to deal with file errors like this in the future?
The issue is that if I uncomment any 1 of the 3 lines at the bottom the BufferedReader reads every other line.
Correct. If you put any of those lines of code in, the line of text read will be thrown away and not processed. You're already reading in the while condition. You don't need another read. If you put any of those lines in, they will be thrown away and not proce
A compilable version of the code posted could be
public void read() throws IOException {
File file = new File(FILE_INPUT_NAME);
FileReader fr = new FileReader(file);
BufferedReader readFile = new BufferedReader(fr);
String line;
while ((line = readFile.readLine()) != null) {
String[] split = line.split(" ", 4);
if (split.length != 4) { // Not enough tokens (e.g., empty line) read
continue;
}
String id = split[0];
String nameFromFile = split[1];
String year = split[2];
String mark = split[3];
int idFromFile = Integer.parseInt(id);
int yearOfStudyFromFile = Integer.parseInt(year);
int markFromFile = Integer.parseInt(mark);
//line = readFile.readLine();
//readFile.readLine();
//System.out.println(readFile.readLine());
}
}
The above uses a single space (" " instead of the original " "). To split on any number of changes, a regular expression can be used, e.g. "\\s+". Of course, exactly 2 spaces can also be used, if that reflects the structure of the input data.
What the method should do with the extracted values (e.g., returning them in an object of some type, or saving them to a database directly), is up to the application using it.
Help again guys, why do I always get this kind of error when using scanner, even though I'm sure that the file exists.
java.util.NoSuchElementException: No line found
I am trying to count the number of occurences of a by using for loop. the text file contain lines of sentence. At the same time, I want to print the exact format of sentences.
Scanner scanLine = new Scanner(new FileReader("C:/input.txt"));
while (scanLine.nextLine() != null) {
String textInput = scanLine.nextLine();
char[] stringArray = textInput.toCharArray();
for (char c : stringArray) {
switch (c) {
case 'a':
default:
break;
}
}
}
while(scanLine.nextLine() != null) {
String textInput = scanLine.nextLine();
}
I'd say the problem is here:
In your while condition, you scan the last line and come to EOF. After that, you enter loop body and try to get next line, but you've already read the file to its end. Either change the loop condition to scanLine.hasNextLine() or try another approach of reading files.
Another way of reading the txt file can be like this:
BufferedReader reader = new BufferedReader(new InputStreamReader(new BufferedInputStream(new FileInputStream(new File("text.txt")))));
String line = null;
while ((line = reader.readLine()) != null) {
// do something with your read line
}
reader.close();
or this:
byte[] bytes = Files.readAllBytes(Paths.get("text.txt"));
String text = new String(bytes, StandardCharsets.UTF_8);
You should use : scanner.hasNextLine() instead of scanner.nextLine() in the while condition
Scanner implements the Iterator interface which works by this pattern:
See if there is a next item (hasNext())
Retrieve the next item (next())
To count the number of occurrences of "a" or for that matter any string in a string, you can use StringUtils from apache-commons-lang like:
System.out.println(StringUtils.countMatches(textInput,"a"));
I think it will be more efficient than converting the string to character array and then looping over the whole array to find the number of occurrences of "a". Moreover, StringUtils methods are null safe
I have been trying to figure this out for couple of hours now and I hope one of you can help me. I have an file (actually two but thats not important) that have some rows and columns with numbers and blank spaces between. And I'm trying to read those with BufferedReader. And that works great. I can print out the strings & chars however I want. But when I try to parse those strings and chars I get the following error:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at FileProcess.processed(FileProcess.java:30)
at DecisionTree.main(DecisionTree.java:16)
From what I have found with google I think the error is located in how I read my file.
public class ReadFiles {
private BufferedReader read;
public ReadFiles(BufferedReader startRead) {
read = startRead;
}
public String readFiles() throws IOException {
try {
String readLine = read.readLine().trim();
String readStuff = "";
while(readLine != null) {
readStuff += (readLine + "\n");
readLine = read.readLine();
}
return readStuff;
}
catch(NumberFormatException e) {
return null;
}
}
And for the parsing bit
public class FileProcess {
public String processed() throws IOException {
fileSelect fs = new fileSelect();
ReadFiles tr = new ReadFiles(fs.traning());
String training = tr.readFiles();
ReadFiles ts = new ReadFiles(fs.test());
String test = ts.readFiles();
List liste = new List(14,test.length());
String[] test2 = test.split("\n");
for(int i = 0; i<test2[0].length(); i++) {
char tmp = test.charAt(i);
String S = Character.toString(tmp).trim();
//int i1 = Integer.parseInt(S);
System.out.print(S);
}
This isn't the actual code for what I planning to do with the output, but the error appears at the code that is commented out. So my string output is as following:
12112211
Which seems good to parse to integer. But it does not work. I tried to manually see what's in the char position 0 and 1, for 0 I get 1, but for 1 I get nothing aka "". So how can I remove the ""? I hope you guys can help me out, and let me know if you need more info. But I think I have covered what's needed.
Thanks in advance :)
Yeah, and another thing: If I replace "" with "0" it works, but then I get all those zeros which I can't find a clever way to remove. But is it possible to maybe skip them while parsing or something? My files only hold 1 and 2, so it wouldn't interfere with anything if it is possible.
The string "" will be returned if you have 2 of the splitting characters next to each other (i.e. \n\n) or if there is a whitespace character being passed into the trim() call so ignore empty strings and carry on.
You could use the Scanner class to parse for ints, skipping Whitespace:
sc = new java.util.Scanner (line);
sc.nextInt ();
Another idea is to trim the line, split, and parse the parts:
lin = line.trim ();
String [] words = lin.split (" +");
for (String si : words)
Integer.parseInt (si);
I have a scanner in my program that reads in parts of the file and formats them for HTML. When I am reading my file, I need to know how to make the scanner know that it is at the end of a line and start writing to the next line.
Here is the relevant part of my code, let me know if I left anything out :
//scanner object to read the input file
Scanner sc = new Scanner(file);
//filewriter object for writing to the output file
FileWriter fWrite = new FileWriter(outFile);
//Reads in the input file 1 word at a time and decides how to
////add it to the output file
while (sc.hasNext() == true)
{
String tempString = sc.next();
if (colorMap.containsKey(tempString) == true)
{
String word = tempString;
String color = colorMap.get(word);
String codeOut = colorize(word, color);
fWrite.write(codeOut + " ");
}
else
{
fWrite.write(tempString + " ");
}
}
//closes the files
reader.close();
fWrite.close();
sc.close();
I found out about sc.nextLine(), but I still don't know how to determine when I am at the end of a line.
If you want to use only Scanner, you need to create a temp string instantiate it to nextLine() of the grid of data (so it returns only the line it skipped) and a new Scanner object scanning the temp string. This way you're only using that line and hasNext() won't return a false positive (It isn't really a false positive because that's what it was meant to do, but in your situation it would technically be). You just keep nextLine()ing the first scanner and changing the temp string and the second scanner to scan each new line etc.
Lines are usually delimitted by \n or \r so if you need to check for it you can try doing it that way, though I'm not sure why you'd want to since you are already using nextLine() to read a whole line.
There is Scanner.hasNextLine() if you are worried about hasNext() not working for your specific case (not sure why it wouldn't though).
you can use the method hasNextLine to iterate the file line by line instead of word by word, then split the line by whitespaces and make your operations on the word
here is the same code using hasNextLine and split
//scanner object to read the input file
Scanner sc = new Scanner(file);
//filewriter object for writing to the output file
FileWriter fWrite = new FileWriter(outFile);
//get the line separator for the current platform
String newLine = System.getProperty("line.separator");
//Reads in the input file 1 word at a time and decides how to
////add it to the output file
while (sc.hasNextLine())
{
// split the line by whitespaces [ \t\n\x0B\f\r]
String[] words = sc.nextLine().split("\\s");
for(String word : words)
{
if (colorMap.containsKey(word))
{
String color = colorMap.get(word);
String codeOut = colorize(word, color);
fWrite.write(codeOut + " ");
}
else
{
fWrite.write(word + " ");
}
}
fWrite.write(newLine);
}
//closes the files
reader.close();
fWrite.close();
sc.close();
Wow I've been using java for 10 years and have never heard of scanner!
It appears to use white space delimiters by default so you can't tell when an end of line occurs.
Looks like you can change the delimiters of the scanner - see the example at Scanner Class:
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt());
System.out.println(s.nextInt());
System.out.println(s.next());
System.out.println(s.next());
s.close();