Reading integers from text file - java

I am trying to read integers from a text file but I failed.
(It fails to read even the first integer)
public void readFromFile(String filename) {
File file = new File(filename);
try {
Scanner scanner = new Scanner(file);
if (scanner.hasNextInt()) {
int x = scanner.nextInt();
}
scanner.close();
} catch (FileNotFoundException e) {
System.out.println("File to load game was not found");
}
}
The error I get is: NoSuchElementException.
The file looks like this:
N,X1,Y1,X2,Y2,X3,Y3
While n equals 3 in this example.
I call this method a in the main method like this:
readFromFile("file.txt");

I am not sure whether you would like to display only the integers after separating them from the string. If that is the case, I would suggest you to use BufferedInputStream.
try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)))){
String input = br.readLine();
int count = 0;
for(int i = 0; i < input.length()- 1; i++){
if(isNumeric(input.charAt(i))){
// replace the Sysout with your own logic
System.out.println(input.charAt(i));
}
}
} catch (IOException ex){
ex.printStackTrace();
}
where isNumeric can be defined as follows:
private static boolean isNumeric(char val) {
return (val >= 48 && val <=57);
}

Scanneruses whitespace as the default delimiter. You can change that with useDelimiter See here: https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

Related

Where do I place the return of a function in JAVA?

I'm trying to figure out how to make a function in JAVA that searches through a document line per line:
First I initialize the file and a reader, then convert each line to a string in an ArrayList; after that I try to check the ArrayList against a String to then return the position of the ArrayList as a string.
So for example I have a text containing:
1 - Somewhere over the rainbow
2 - Way up high.
Converted to ArrayList, if then searched for: "Somewhere"; then it should return the sentence "Somewhere over the rainbow";
Here is the code I tried; but it keeps returning 'null';
String FReadUtilString(String line) {
File file = new File(filepath);
ArrayList<String> lineReader = new ArrayList<String>();
System.out.println();
try {
Scanner sc = new Scanner(file);
String outputReader;
while (sc.hasNextLine()) {
lineReader.add(sc.nextLine());
}
sc.close();
for(int count = 0; count < lineReader.size(); count++) {
if(lineReader.get(count).contains(line)){outputReader = lineReader.get(count);}
}
} catch (Exception linereadeline) {
System.out.println(linereadeline);
}
return outputReader;
}
I refactor your code a bit, but I keep your logic, it should work for you:
String FReadUtilString(String line, String fileName){
File file = new File(fileName);
List<String> lineReader = new ArrayList<>();
String outputReader = "";
try (Scanner sc = new Scanner(file))
{
while (sc.hasNextLine()) {
lineReader.add(sc.nextLine());
}
for (int count = 0; count < lineReader.size(); count++){
if (lineReader.get(count).contains(line)){
outputReader = lineReader.get(count);
}
}
}
catch (Exception linereadeline) {
System.out.println(linereadeline);
}
return outputReader;
}
NOTE: I used the try-with-resource statement to ensure the closing of the Scanner.
A more succinct version:
String fReadUtilString(String line, String fileName) {
try (Stream<String> lines = Files.lines(Paths.get(fileName))) {
return lines.filter(l -> l.contains(line)).findFirst();
}
catch (Exception linereadeline) {
System.out.println(linereadeline); // or just let the exception propagate
}
}

Scanner for input file and storing data objects from input file in array

Basically, I had to create a scanner for a given file and read through the file (the name is input through the terminal by the user) once counting the number of lines in the file. Then after, I had to create an array of objects from the file, of the correct size (where the num of lines comes in). Then I had to create another scanner for the file and read through it again, storing it in the array I created. And lastly, had to return the array in the method.
My problem is I cannot seem to get the second scanner to actually store the file objects in the array.
I've tried using .nextLine inside a for loop that also calls the array, but it doesn't seem to be working.
public static Data[] getData(String filename) {
Scanner input = new Scanner(new File(filename));
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
System.out.println(count);
Data[] data = new Data[count];
Scanner input1 = new Scanner(new File(filename));
while (input1.hasNextLine()) {
for (int i = 0; i < count; i++) {
System.out.println(data[i].nextLine);
}
}
return data;
}
I expect the output to successfully read the input file so that it can be accessed by other methods that I have created (not shown).
You should definitely use an IDE if you don't have one, try intellij... There you have autocompletion and syntax checking and much more.
It is not clear what you want to do in your for loop, because there are several mistakes, for example the readline() function works only with the scanner objekt, so you can do input.nextline() or input1.nextline()`...
so I just show you, how you can get the Data from a file with Scanner:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Readfile {
public static void getData(String filename) throws FileNotFoundException {
ArrayList<String> test = new ArrayList<>(); //arraylist to store the data
Scanner inputSc = new Scanner(new File(filename)); //scanner of the file
while (inputSc.hasNextLine()) {
String str = inputSc.nextLine();
System.out.println(str); //print the line which was read from the file
test.add(str); //adds the line to the arraylist
//for you it would be something like data[i] = str; and i is a counter
}
inputSc.close();
}
public static void main(String[] args) {
try {
getData("/home/user/documents/bla.txt"); //path to file
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
You don't need to read thru the file twice - just use an ArrayList to hold the data that's coming in from the file, like this, and then return Data[] at the end:
public static Data[] getData(String filename) {
List<Data> result = new ArrayList<>();
try (Scanner input = new Scanner(new File(filename))){
while (input.hasNextLine()) {
Data data = new Data(input.nextLine());
result.add(data);
}
}
return result.toArray(new Data[0]);
}
Not clear what Data.class do you mean, if you switch it to String, the problem obviously would be in this line
System.out.println(data[i].nextLine);
if you want to assign and print simultaneously write this
for (int i = 0; i < count; i++) {
data[i] = input1.next();
System.out.println(data[i]);
}
and dont forget to close your Scanners, better use try-with-resources.
If your Data is your custom class you'd better learn about Serialization-Deserialization
Or use some ObjectMapper-s(Jackson, for example) to store your class instances and restore them.
Your way of opening the file just to count the lines and then again looping through its lines to store them in the array is not that efficient, but it could be just a school assignment.
Try this:
public static Data[] getData(String filename) {
Scanner input = null;
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
input.close();
System.out.println(count);
Data[] data = new Data[count];
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
for (int i = 0; i < count; i++) {
Data d = new Data(input.nextLine(), 0, 0);
data[i] = d;
System.out.println(data[i].name);
}
input.close();
return data;
}
After the 1st loop you must close the Scanner and reopen it so to start all over from the first line of the file.

Reading a text file into a 2D array

I need to read a text file into a 2D array, I can read files into the program perfectly fine (see my code below) however I cannot get my head around how to read them into a 2D array. The array the function is reading into is a global array hence why it's not in the function.
Also I won't know the amount of rows the array has at first (currently set at 300 as it won't be over this) and I know this could cause a problem, I've seen some people suggest using ArrayLists however I have to have a 2D array so I was also wondering if there was a way to change an ArrayList to a 2D array and if this would be more effective?
public static String readMaze(String fileName) {
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
for (int i = 0; i < mazeNew.length; i++) {
for (int j = 0; j < mazeNew[i].length; j++) {
// mazeNew[i][j] = ; - this is where I think something needs to be added
}
}
}
bufferedReader.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return fileName;
}
example text file:
11 4
5 6
4 6
0 5
3 5
8 7
1 4
There's a few options here, but generally you'll want to use the Java Scanner class as it's designed for exactly this kind of thing. Alternatively, use an existing structured data format (like JSON or XML) and an existing parser to go with it - the advantage being you can make use of a vast amount of tools and libraries which deal with those formats and don't have to re-invent anything.
However, following through with the scanner approach, it would be like so:
public static ArrayList<int[]> readMaze(String fileName) {
// Number of ints per line:
int width=2;
// This will be the output - a list of rows, each with 'width' entries:
ArrayList<int[]> results=new ArrayList<int[]>();
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
Scanner mazeRunner = new Scanner(bufferedReader);
// While we've got another line..
while (mazeRunner.hasNextLine()) {
// Setup current row:
int[] row = new int[width];
// For each number..
for (int i = 0; i < width; i++) {
// Read the number and add it to the current row:
row[i] = mazeRunner.nextInt();
}
// Add the row to the results:
results.add(row);
// Go to the next line (optional, but helps deal with erroneous input files):
if ( mazeRunner.hasNextLine() ) {
// Go to the next line:
mazeRunner.nextLine();
}
}
mazeRunner.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file: " + fileName);
}
catch (IOException ex) {
System.out.println("Error reading file: " + fileName);
}
return results;
}
If you have fixed no. of columns you can use this, but make sure input file must follow the same no of coulmns.
FileReader fileReader = new FileReader(fileName);
Scanner sc = new Scanner(fileReader);
int row=0, col=0;
while ((sc.hasNext()) != null) {
if(col < colSize){ //colSize is size of column
mazeNew[row][col]= sc.nextInt();
}
else{
col=0;
row++;
}
}
Below is the core logic, you would probably also like to to handle some errors, such as how many elements is a line split into, are there empty lines, etc.
List<String[]> list = new ArrayList<>();
Pattern pattern = Pattern.compile("\\s+");
while ((line = bufferedReader.readLine()) != null) {
list.add(pattern.split(line, -1));
}
String[][] mazeNew = list.toArray(new String[0][0]);
Something like this would work
it wont only read 2d text files .. it should work fine with any dimensions
public class Utile{
public static ArrayList<int[]> readMaze(String path){
ArrayList<int[]> result = new ArrayList<>();
try{
Scanner sc = new Scanner(new File(path));
String[] temp;
String line;
while(sc.hasNextLine()){
line = sc.nextLine();
if (line.length() != 0){ //if the line is empty it will cause NumberFormatException
temp = line.split(" ");
int[] val = new int[temp.length];
for(int i = 0;i < temp.length;i++){
val[i] = Integer.pareseInt(temp[i]);
}
result.add(val);
}
}
sc.close();
}catch(Exception e){
e.printStackTrace(); //just log it for now
}
return result;
}
}
I am not a java expert, but in PHP I would do it with explode(). But I found an example how to do the same in java using string.split(). The result is the same ... an 2D Array of the content. If possible you should try to add an delimiter to the rows inside that text document. But you could split the rows on the space character either.
Example:
String foo = "This,that,other";
String[] split = foo.split(",");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
sb.append(split[i]);
if (i != split.length - 1) {
sb.append(" ");
}
}
String joined = sb.toString();

Reading text file always returns 0 - Java

I'm trying to read a text file to get a version number but for some reason no matter what I put in the text file it always returns 0 (zero).
The text file is called version.txt and it contains no spaces or letters, just 1 character that is a number. I need it to return that number. Any ideas on why this doesn't work?
static int i;
public static void main(String[] args) {
String strFilePath = "/version.txt";
try
{
FileInputStream fin = new FileInputStream(strFilePath);
DataInputStream din = new DataInputStream(fin);
i = din.readInt();
System.out.println("int : " + i);
din.close();
}
catch(FileNotFoundException fe)
{
System.out.println("FileNotFoundException : " + fe);
}
catch(IOException ioe)
{
System.out.println("IOException : " + ioe);
}
}
private final int VERSION = i;
Here is the default solution that i use whenever i require to read a text file.
public static ArrayList<String> readData(String fileName) throws Exception
{
ArrayList<String> data = new ArrayList<String>();
BufferedReader in = new BufferedReader(new FileReader(fileName));
String temp = in.readLine();
while (temp != null)
{
data.add(temp);
temp = in.readLine();
}
in.close();
return data;
}
Pass the file name to readData method. You can then use for loop to read the only line in the arraylist, and can use the same loop to read multiple lines from different file...I mean do whatever you like with the arraylist.
Please don't use a DataInputStream
Per the linked Javadoc, it lets an application read primitive Java data types from an underlying input stream in a machine-independent way. An application uses a data output stream to write data that can later be read by a data input stream.
You want to read a File (not data from a data output stream).
Please do use try-with-resources
And since you seem to want an ascii integer, I'd suggest you use a Scanner.
public static void main(String[] args) {
String strFilePath = "/version.txt";
File f = new File(strFilePath);
try (Scanner scanner = new Scanner(f)) {
int i = scanner.nextInt();
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
}
}
Use an initializing block
An initializing block will be copied into the class constructor, in your example remove public static void main(String[] args), something like
private int VERSION = -1; // <-- no more zero!
{
String strFilePath = "/version.txt";
File f = new File(strFilePath);
try (Scanner scanner = new Scanner(f)) {
VERSION = scanner.nextInt(); // <-- hope it's a value
System.out.println("Version = " + VERSION);
} catch (Exception e) {
e.printStackTrace();
}
}
Extract it to a method
private final int VERSION = getVersion("/version.txt");
private static final int getVersion(String strFilePath) {
File f = new File(strFilePath);
try (Scanner scanner = new Scanner(f)) {
VERSION = scanner.nextInt(); // <-- hope it's a value
System.out.println("Version = " + VERSION);
return VERSION;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
or even
private final int VERSION = getVersion("/version.txt");
private static final int getVersion(String strFilePath) {
File f = new File(strFilePath);
try (Scanner scanner = new Scanner(f)) {
if (scanner.hasNextInt()) {
return scanner.nextInt();
}
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}

how do u read all doubles from txt file?

Its easy when have a file of all doubles, but when
there is a non-double somewhere in between,
i wouldnt be able to catch all of them.
For example:
604.2
609.2
6042
604.4
4234.324
312
gfsdgfreg
6043
604.3
The output:
604.2
609.2
6042.0
604.4
4234.324
312.0
Apparently, two doubles are missing. Is there a way
to catch all of them just by using hasNextDouble()?
Thx in advance if u dont get a reply. I saw somewhere
that I could parse each of them to double and catch the
exception, but i am really not that advanced
what i have here is:
import java.util.*;
import java.io.*;
public class Lab11{
public static void main(String[] args)
throws FileNotFoundException{
File nums = new File("file.txt");
int size = arrSize(nums);
double[] phoneNums = copy(nums,size);
for(int i=0;i<phoneNums.length;i++)
System.out.println(phoneNums[i]);
}
public static int arrSize(File f)
throws FileNotFoundException{
int arrSize = 0;
Scanner in = new Scanner(f);
while(in.hasNextDouble()){
arrSize++;
in.next();
}
in.close();
return arrSize;
}
public static double[] copy(File f,int size)
throws FileNotFoundException{
Scanner in = new Scanner(f);
double[] list = new double[size];
int i = 0;
while(in.hasNextDouble()){
list[i++] = in.nextDouble();
}
in.close();
return list;
}
}
I would give your two while loops the following structure:
while(in.hasNext()) {
if(in.hasNextDouble()) {
// your inner while loop code here
} else {
in.next();
}
}
Otherwise, you'll miss everything after the first instance of a non-double.
Since you are using
while(in.hasNextDouble()){
arrSize++;
in.next();
}
As soon as it reaches a non-double, it will stop, and won't proceed further.
You have to keep looping through every line in the while loop, and within this loop, use an if statement to check whether what you're reading is a double or not.
Like Takendarkk said, once a non-double is found in the input in.hasNextDouble() will evaluate to false, ending your loop.
Here is an example of a (hopefully) more simplified way of doing what you are doing:
// create a new list for our doubles
List<Double> doubles = new LinkedList<>();
try {
// open our doubles file reader
BufferedReader reader = Files.newBufferedReader(Paths.get("doubles.txt"), Charset.defaultCharset());
// read our doubles file
String line;
while ((line = reader.readLine()) != null) {
if (line.matches("^[0-9]*(\\.[0-9]+)?$")) {
doubles.add(Double.parseDouble(line));
}
}
// close our doubles file reader
reader.close();
} catch (IOException e) {
e.printStackTrace(); // for the sake of the example
}
// output our doubles
for (Double d : doubles) {
System.out.println("Double: " + d);
}
Hope this helps

Categories

Resources