I'm reading a file into an array and trying to take out the numbers and put them as a double in an array of their own. And apparently my middle name must be "Error". From what I can tell the code is ok....at least theres nothing jumping out at me. Here it is in all it's glory.
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import java.lang.Object.*;
public class ReadFromFile {
public static void main (String[] args){
File file = new File("vector10.txt");
FileInputStream fis = null;
BufferedInputStream bis = null;
DataInputStream dis = null;
StringBuffer sb = new StringBuffer();
String string = new String();
try{
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
while((string=dis.readLine()) != null){
sb.append(string+"\n");
}
fis.close();
bis.close();
dis.close();
System.out.println(sb);
String newString = sb.toString();
System.out.println(newString);
String[] doubles = newString.split(",");
for (int i=0; i<doubles.length; i++){
System.out.println(doubles[i]);
}
Double arrDouble[] = new Double[doubles.length];
int idx = 0;
for(String s : doubles) {
arrDouble[idx++] = Double.parseDouble(s);
}
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
It keeps throwing an error
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:412)
at java.lang.Long.parseLong(Long.java:461)
at ReadFromFile.main(ReadFromFile.java:51)
Programming is not necessarily my strong point and my eyes are starting to bleed looking at the screen.
Any thoughts or tips are gratefully appreciated.
Cheers
If your file is comma separated then it's better to use Scanner
String doubles = "1.25, 1.65, 1.47";
Scanner f = new Scanner(doubles);
f.useLocale(Locale.US); //without this line the program wouldn't work
//on machines with different locales
f.useDelimiter(",\\s*");
while (f.hasNextDouble()) {
System.out.println(f.nextDouble());
}
Maybe you can try using Scanner class?
Scanner sc = new Scanner(new File("vector10.txt"));
ArrayList<Double> lst = new ArrayList<Double>();
while (sc.hasNextDouble()) {
lst.add(new Double(sc.nextDouble()));
}
Your code doesn't seem to be the one actually run, but in your code, you are building a big string of all your numbers, separated by newlines. But then you split it (using String.split) at commas, and there are no commas in that string. So Double.parseDouble gets all the numbers at once.
The error says that you are calling Long.parseLong(), not Double.parseDouble(), as the code you posted says. Perhaps you forgot to recompile?
That could be the whole problem, but if not send a System.out.println(string) of the value you are going to call Double.parseDouble(string) right before so you can see the value it fails on.
Double.parseDouble() like all parse* methods do not react well to characters that they don't expect, and that - unfortunately - includes white space. A few spaces in your string can ruin your whole day.
To solve, first it will be a good idea to split on spaces as well, so something like newString.split("[,\\s]+") would work nicely by splitting and removing any sequence of white-space and/or commas. Then when you try to parse, trim your string - just for safety - something like Double.parseDouble(doubles[i].trim()). For extra safety, check if your trimmed string is not the empty string before parsing - maybe something like if (doubles[i].trim().length() < 1) continue;.
Good luck.
Related
I was searching on the internet and came across this code to read files from a file and convert it into a string. But I don't understand how in.read(arr) is reading all the contents of a file at once.
import java.util.Scanner;
import java.io.*;
class Main{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String s = sc.next();
try
{
File file = new File(s);
BufferedReader in = new BufferedReader(new FileReader(file));
int c;
char arr[] = new char[(int)file.length()];
in.read(arr);
String res = new String(arr);
System.out.println(res);
}
catch(Exception e){}
}
}
In contemporary Java code you would use Files.readString for this purpose. It was introduced with Java 11, and it specifically reads an entire text file into a String.
What happens in the code you ask about is a common thing with read(someArray) methods: they read up to a number of conditions, something like
The specified number of characters have been read,
The read method of the underlying stream returns -1, indicating end-of-file, or
The ready method of the underlying stream returns false, indicating that further input requests would block.
here you use the first and second conditions, and hope that the third one will not kick in, so reading from a local file won't cause "blocking" at an arbitrary file position.
File.length tells you the size of the file in bytes. There can't be more characters in a file than its size in bytes, that's why file.length is a good upper estimate for the number of characters you would need. However as there are encodings which can result a single character stored as multiple bytes (such as UTF-8), you should actually use the return value of that read() call which tells you the number of characters read, and then pass it to the String constructor:
char arr[] = new char[(int)file.length()];
int count = in.read(arr);
String res = new String(arr, 0, count);
Actual variants of your code:
with File.toPath() if you like
import java.util.Scanner;
import java.io.File;
import java.nio.file.Files; // "Files" is needed of course
class Main
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String s = sc.next();
try
{
File file = new File(s);
String res = Files.readString(file.toPath()); // many lines disappeared
System.out.println(res);
}
catch (Exception e) {}
}
}
with java.nio classes and interfaces:
import java.util.Scanner;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
class Main
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String s = sc.next();
try
{
Path path = Paths.get(s); // "File file" became "Path path"
String res = Files.readString(path); // many lines disappeared again
System.out.println(res);
}
catch (Exception e) {}
}
}
It's up to a bit of taste and what you have already. If you have a File object anyway (like you need its size for some another purpose, or you get it from GUI code for example - in many cases that's going to be a File), use its toPath(). If you have a String, a single Paths.get() is less typing.
The object 'in' has the information related to file.
'arr' is the array whose length is equal to the length of file contents.
Then 'in' is read upto that length of file
I need to have this file print to an array, not to screen.And yes, I MUST use an array - School Project - I'm very new to java so any help is appreciated. Any ideas? thanks
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class HangmanProject
{
public static void main(String[] args) throws FileNotFoundException
{
String scoreKeeper; // to keep track of score
int guessesLeft; // to keep track of guesses remaining
String wordList[]; // array to store words
Scanner keyboard = new Scanner(System.in); // to read user's input
System.out.println("Welcome to Hangman Project!");
// Create a scanner to read the secret words file
Scanner wordScan = null;
try {
wordScan = new Scanner(new BufferedReader(new FileReader("words.txt")));
while (wordScan.hasNext()) {
System.out.println(wordScan.next());
}
} finally {
if (wordScan != null) {
wordScan.close();
}
}
}
}
Nick, you just gave us the final piece of the puzzle. If you know the number of lines you will be reading, you can simply define an array of that length before you read the file
Something like...
String[] wordArray = new String[10];
int index = 0;
String word = null; // word to be read from file...
// Use buffered reader to read each line...
wordArray[index] = word;
index++;
Now that example's not going to mean much to be honest, so I did these two examples
The first one uses the concept suggested by Alex, which allows you to read an unknown number of lines from the file.
The only trip up is if the lines are separated by more the one line feed (ie there is a extra line between words)
public static void readUnknownWords() {
// Reference to the words file
File words = new File("Words.txt");
// Use a StringBuilder to buffer the content as it's read from the file
StringBuilder sb = new StringBuilder(128);
BufferedReader reader = null;
try {
// Create the reader. A File reader would be just as fine in this
// example, but hay ;)
reader = new BufferedReader(new FileReader(words));
// The read buffer to use to read data into
char[] buffer = new char[1024];
int bytesRead = -1;
// Read the file to we get to the end
while ((bytesRead = reader.read(buffer)) != -1) {
// Append the results to the string builder
sb.append(buffer, 0, bytesRead);
}
// Split the string builder into individal words by the line break
String[] wordArray = sb.toString().split("\n");
System.out.println("Read " + wordArray.length + " words");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
}
}
}
The second demonstrates how to read the words into an array of known length. This is probably closer to the what you actually want
public static void readKnownWords()
// This is just the same as the previous example, except we
// know in advance the number of lines we will be reading
File words = new File("Words.txt");
BufferedReader reader = null;
try {
// Create the word array of a known quantity
// The quantity value could be defined as a constant
// ie public static final int WORD_COUNT = 10;
String[] wordArray = new String[10];
reader = new BufferedReader(new FileReader(words));
// Instead of reading to a char buffer, we are
// going to take the easy route and read each line
// straight into a String
String text = null;
// The current array index
int index = 0;
// Read the file till we reach the end
// ps- my file had lots more words, so I put a limit
// in the loop to prevent index out of bounds exceptions
while ((text = reader.readLine()) != null && index < 10) {
wordArray[index] = text;
index++;
}
System.out.println("Read " + wordArray.length + " words");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
}
}
}
If you find either of these useful, I would appropriate it you would give me a small up-vote and check Alex's answer as correct, as it's his idea that I've adapted.
Now, if you're really paranoid about which line break to use, you can find the values used by the system via the System.getProperties().getProperty("line.separator") value.
Do you need more help with the reading the file, or getting the String to a parsed array? If you can read the file into a String, simply do:
String[] words = readString.split("\n");
That will split the string at each line break, so assuming this is your text file:
Word1
Word2
Word3
words will be: {word1, word2, word3}
If the words you are reading are stored in each line of the file, you can use the hasNextLine() and nextLine() to read the text one line at a time. Using the next() will also work, since you just need to throw one word in the array, but nextLine() is usually always preferred.
As for only using an array, you have two options:
You either declare a large array, the size of whom you are sure will never be less than the total amount of words;
You go through the file twice, the first time you read the amount of elements, then you initialize the array depending on that value and then, go through it a second time while adding the string as you go by.
It is usually recommended to use a dynamic collection such as an ArrayList(). You can then use the toArray() method to turnt he list into an array.
I'm trying to remove the commas from the following txt file:
abcd,efgh,ijkl
mnop,qrst,uvwx
yzzz,0123,4567
8910
My code goes something like this:
public static ArrayList readFileByLine(ArrayList list, String fileName){
try{
File file = new File(fileName);
Scanner reader = new Scanner(file);
reader.useDelimiter(",");
while(reader.hasNext()){
String s = reader.next();
s= s.trim();
s= s.replaceAll("," , "");
list.add(s);
}
reader.close();
}
catch(FileNotFoundException e){ System.err.println("Error: " + e.getMessage());}
return list;
}
I'm trying not to use a regex unless absolutely necessary, if you recommend that I use a regex please explain what it does! Thanks for the help!
Your code runs fine. I think you were running into other issues, I'm not sure what. Here's the code that I used (your code with some modifications):
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
List<String> list = readFileByLine(new ArrayList<String>(), "/Users/hassan/Library/Containers/com.apple.TextEdit/Data/Desktop/file.text");
for(String s : list){
System.out.println(s);
}
}
public static List<String> readFileByLine(ArrayList<String> list, String fileName){
try{
File file = new File(fileName);
Scanner reader = new Scanner(file);
reader.useDelimiter(",");
while(reader.hasNext()){
String s = reader.next();
s= s.trim();
s= s.replaceAll("," , "");
list.add(s);
}
reader.close();
}
catch(FileNotFoundException e){ System.err.println("Error: " + e.getMessage());}
return list;
}
}
This code works (try it!). I should mention that the way I'm using this code, passing an ArrayList as the first argument is useless, since you can just make a new ArrayList at the beginning of the readFileByLine function. I'm not sure if you did it this way because you want to re-add strings to the array later on, so I left it alone.
import java.io.*;
import java.util.*;
public class Readfilm {
public static void main(String[] args) throws IOException {
ArrayList films = new ArrayList();
File file = new File("filmList.txt");
try {
Scanner scanner = new Scanner(file);
while (scanner.hasNext())
{
String filmName = scanner.next();
System.out.println(filmName);
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}}
Above is the code I'm currently attempting to use, it compiles fine, then I get a runtime error of:
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1416)
at Readfilm.main(Readfilm.java:15)
I've googled the error and not had anything that helped (I only googled the first 3 lines of the error)
Basically, the program I'm writing is part of a bigger program. This part is to get information from a text file which is written like this:
Film one / 1.5
Film two / 1.3
Film Three / 2.1
Film Four / 4.0
with the text being the film title, and the float being the duration of the film (which will have 20 minutes added to it (For adverts) and then will be rounded up to the nearest int)
Moving on, the program is then to put the information in an array so it can be accessed & modified easily from the program, and then written back to the file.
My issues are:
I get a run time error currently, not a clue how to fix? (at the moment I'm just trying to read each line, and store it in an array, as a base to the rest of the program) Can anyone point me in the right direction?
I have no idea how to have a split at "/" I think it's something like .split("/")?
Any help would be greatly appreciated!
Zack.
Your code is working but it reads just one line .You can use bufferedReader here is an example import java.io.*;
class FileRead
{
public static void main(String args[])
{
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("textfile.txt");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
And here is an split example class StringSplitExample {
public static void main(String[] args) {
String st = "Hello_World";
String str[] = st.split("_");
for (int i = 0; i < str.length; i++) {
System.out.println(str[i]);
}
}
}
I wouldn't use a Scanner, that's for tokenizing (you get one word or symbol at a time). You probably just want to use a BufferedReader which has a readLine method, then use line.split("/") as you suggest to split it into two parts.
Lazy solution :
Scanner scan = ..;
scan.nextLine();
I have the following code but I don't understand how I can reset the pointer to the starter position:
BufferedReader inp=new BufferedReader(new FileReader(file));
Scanner leggi=new Scanner(inp);
for(int i=0;i<nwords;i++){
while(leggi.hasNext())
if(leggi.next().equals(args[i+2]))
occorrenze[i]=occorrenze[i]+1;
}
inp.close();
I tried
inp.mark(0);
inp.reset();
with no results.
Paul,
I suggest you read through this old thread: Java BufferedReader back to the top of a text file?.
Personally I prefer Jon Skeet's response, which boils down to "Don't bother [unless you MUST]."
Cheers. Keith.
EDIT: Also you should ALLWAYS close that input file, even if you hit an Exception. The finally block is perfect for this.
EDIT2:
Hope you're still with us.
Here's my attempt, and FWIW, you DON'T need to reset the input-file, you just need to transpose your while and for loops.
package forums;
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class WordOccurrenceCount
{
public static void main(String[] args) {
try {
String[] words = { "and", "is", "a", "the", "of", "as" };
int[] occurrences = readOccurrences("C:/tmp/prose.txt", words);
for ( int i=0; i<words.length; i++ ) {
System.out.println(words[i] + " " + occurrences[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static final int[] readOccurrences(String filename, String... words)
throws IOException
{
int[] occurrences = new int[words.length];
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(filename));
Scanner scanner = new Scanner(reader);
while ( scanner.hasNext() ) {
String word = scanner.next();
for ( int i=0; i<words.length; i++ ) {
if ( words[i].equals(word) ) {
occurrences[i]++;
}
}
}
} finally {
if(reader!=null) reader.close();
}
return occurrences;
}
}
And BTW, java.util.Map is perfect for building a frequency table... Parallel arrays are just SOOOOO 90's. The "default" implementation of Map is the HashMap class... By default I mean use HashMap whenever you need a Map, unless you've got a good reason to use something else, which won't be often. HashMap is generally the best allround performer.
You have two options:
reset the FileReader (FieldReader.reset) instead and create a new bufferedreader.
use mark functionaliy (try BufferedReader.markSupported)
I think what you tried is to call mark after you read the input. Instead do the following:
inp.mark(readAheadLimit);
// .... all your code processing input
inp.reset();
mark(int readAheadLimit) takes a readAheadLimit parameter.
You should not set the readAheadLimit to 0. Try using a meaningful number that is larger than number of bytes you read in an iteration.