I'm having issues reading and storing only integers from a text file. I'm using a int array so I want to do this without list. I'm getting a input mismatch exception, and I don't know how I should go about correcting that issue. The text files being read from also include strings.
public static Integer[] readFileReturnIntegers(String filename) {
Integer[] array = new Integer[1000];
int i = 0;
//connect to the file
File file = new File(filename);
Scanner inputFile = null;
try {
inputFile = new Scanner(file);
}
//If file not found-error message
catch (FileNotFoundException Exception) {
System.out.println("File not found!");
}
//if connected, read file
if(inputFile != null){
System.out.print("number of integers in file \""
+ filename + "\" = \n");
//loop through file for integers and store in array
while (inputFile.hasNext()) {
array[i] = inputFile.nextInt();
i++;
}
inputFile.close();
}
return array;
}
You might use something like this (to skip over any non-int(s)), and you should close your Scanner!
// if connected, read file
if (inputFile != null) {
System.out.print("number of integers in file \""
+ filename + "\" = \n");
// loop through file for integers and store in array
try {
while (inputFile.hasNext()) {
if (inputFile.hasNextInt()) {
array[i] = inputFile.nextInt();
i++;
} else {
inputFile.next();
}
}
} finally {
inputFile.close();
}
// I think you wanted to print it.
System.out.println(i);
for (int v = 0; v < i; v++) {
System.out.printf("array[%d] = %d\n", v, array[v]);
}
}
Change hasNext() to hasNextInt() in your while loop.
What you need to do is before you get a new value and try to put it into the array you need to check to make sure that it is in fact an int and if it isn't then skip over it and move on to the next value. Alternately you could make a string array of all of the values and then copy only the integers into a separate array. However, the first solution is probably the better of the two.
Also... As has been mentioned in the comments it tends to be easier to read the integers in as strings and then parse the values from them...
Related
I'm trying to to read the file contents into a character array using the scanner class and I keep getting a string index out of bounds error from my code and I'm not sure what's wrong
File fileName = null;
if(0<args.length) {
fileName = new File(args[0]);
}
Scanner s = null;
try {
s = new Scanner(fileName);
s.useDelimiter(",");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
char[]array = new char[26];
while(s.hasNext()) {
for(int i=0; i<27; i++) {
array[i] = s.next().charAt(i);
}
}
As far as I can tell, your code is equivalent to the following, which has no out of bounds exceptions
char[]array;
while(s.hasNext()) {
array = s.next().toCharArray();
}
However, after that while loop, your array will only equal the very last scanned value.
If you have individual comma separated characters, you can use the following. You do not need a loop within the existing loop
char[]array = new char[26];
int i = 0;
while(s.hasNext()) {
array[i++] = s.next().charAt(0);
}
In any case, I suggest using StringTokenizer rather than a Scanner
In your for loop, you are trying to access a[26] but you have declared memory for 26 characters. So you can access only a[0] to a[25].
The current code that I have reads only the last line of the file. Can someone help me establish a way so that the code reads a file line by line?
import java.util.*;
import java.io.*;
public class Searcher extends File {
Scanner scn;
public Searcher(String filename) {
super(filename);
}
public void search(String input)
{
try {
scn = new Scanner(this);
String data = "";
while (scn.hasNext()) {
data = scn.nextLine();
}
int count = 0, fromIndex = 0;
while ((fromIndex = data.indexOf(input, fromIndex)) != -1) {
count++;
fromIndex++;
}
System.out.println("Total occurrences: " + count);
scn.close();
} catch (Exception e) {
System.out.println("Cant find file ");
}
}
public static void main(String[] args) {
Searcher search = new Searcher("src/ihaveadream.txt");
search.search("we");
}
}
appreciate any help !
while (scn.hasNext()) {
data = scn.nextLine();
}
You are replacing the value every time so you end up with the last value as that's what it gets set to in the end. Perhaps you wanted to append?
while (scn.hasNext()) {
data = data + scn.nextLine();
}
Good luck.
Your problem:
while (scn.hasNext()) {
data = scn.nextLine(); // right here
}
each next line replaces previous line.
Depending on what you need you can either:
make all lines as one String
data = data + scn.nextLine();
// another syntax to do the same:
data += scn.nextLine();
or use List to keep each line as separate element:
List<String> dataList = new ArrayList<>();
while (scn.hasNext()) {
dataList.add(scn.nextLine());
}
As everyone has already suggested, you are replacing the the data in your data variable in the while loop, and since the loop runs till the end of the file is reached, only the last line is stored in the data variable, and any further processing on data would get you results only from the last line, so what you can do is what everybody else here suggested, or you can try this as an alternative solution (close the while loop after you check for index values):
public void search(String input)
{
int count = 0, fromIndex = 0; //moved outside so that we don't reset it to 0 with every iteration of the loop
try {
scn = new Scanner(this);
String data = "";
while (scn.hasNext()) {
data = scn.nextLine();
//} instead of here
//int count = 0, fromIndex = 0; move these variables outside of the loop
while ((fromIndex = data.indexOf(input, fromIndex)) != -1) {
count++;
fromIndex++;
}
} //close it here
System.out.println("Total occurrences: " + count);
scn.close();
} catch (Exception e) {
System.out.println("Cant find file ");
}
}
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();
I am new at Java so please bear with me.
I need help for one of my assignments again. Now it involves FileI/O.
The task that I have to do is:
I have to read a .csv file. The values that's inside the file are:
Christopher Lee,54.0
Stanley Wright,90.5
Oliver Stewart,75.8
Jessica Chang,34.65
As the task said, I must store the contents on the file into two arrays. One for the names, and one for the test marks. I should read the file at least twice, once to check how many names are in the file and a couple more times to actually read the file (to get the names and marks). So basically, I should have an array to store the names as Strings, and an array to store the marks of the student as real numbers.
I should line up the arrays (e.g.students[0] should store the name of the first student and marks[0] should store the mark of the first student
After I stored the contents of the .csv file into an array I have to display a following menu to the user. If the user pressed 1, it should prompt the user to enter the name of a student. If the user pressed 2, the program should exit. If the name exists, it should display the test mark for the student entered. If the student does not exist then I must output a message indicating so to the user, yet the program should not end but return to the above menu.
This is my code so far:
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String fileName = "file:///Documents/Java/marks_file.csv"; // Opens the file
String[] arrayString = new String[6]; // String length inside the file
int numLines, selection = 0;
double[] arrayReal = new double[6]; // Number length inside the file
numLines = getNumLines(fileName); // Gets the length of the file
readFile(arrayString, arrayReal, fileName);
// Selection menu
do
{
System.out.println("Select an option:");
System.out.println("1. Display mark");
System.out.println("2. Exit");
selection = sc.nextInt();
if (selection == 1)
{
System.out.println("Enter your full name");
{
// Do something
}
}
else if (selection == 2)
{
System.out.println("Goodbye");
}
}
while (selection == 1);
//System.out.println("Number of arrays: " + numLines);
}
// Method to get the length of the .csv file
public static int getNumLines(String fileName)
{
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
String line;
int lineNum = 0;
try
{
fileStrm = new FileInputStream(fileName);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
line = bufRdr.readLine();
while (line != null)
{
lineNum = lineNum + 1;
line = bufRdr.readLine();
}
fileStrm.close();
}
catch (IOException e)
{
try
{
if (fileStrm != null)
{
fileStrm.close();
}
}
catch (IOException ex2)
{
// Nothing to do
}
System.out.println("Error in file processing: " + e.getMessage());
}
return lineNum;
}
// Method to store the values to arrays
public static void readFile(String[] arrayString, double[] arrayReal, String fileName)
{
Scanner sc = new Scanner(System.in);
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
String line;
try
{
fileStrm = new FileInputStream(fileName);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
for (int i = 0; i < arrayString.length; i++)
{
line = bufRdr.readLine();
arrayString[i] = processString(line);
arrayReal[i] = processReal(line);
}
}
catch (IOException e)
{
try
{
if (fileStrm != null)
{
fileStrm.close();
}
}
catch (IOException ex2)
{
// Nothing to do
}
System.out.println("Error in file processing: " + e.getMessage());
}
}
// Stores the String lines to array
public static String processString(String line)
{
String string;
String[] lineArray = line.split(",");
return string = lineArray[0];
}
// Stores real number lines to array
public static double processReal(String line)
{
double real;
String[] lineArray = line.split(",");
return real = Double.parseDouble(lineArray[1]);
}
So far, I finished the "reading the file" part and processing the contents from a .csv file to an array.
I am not too sure how to prompt a user to search a string array from a .csv file. I tried looking at other sources, even at this website but I have no luck at all. I tried the Scanner.next() method but that doesn't work at all. Maybe I just missed something. Also, I am not sure if I did the "reading the file twice" right.
Am I on the right track? I am need of some guidance here
First of all I want to say that I'd use a Map instead of two arrays but I'll show you a solution using two arrays.
You were close to the solution. One of you problems is that scanner.next() only reads the input until the first whitespace. That's why you need to use scanner.nextLine(). This method reads the complete line. And the code could look something like that:
Solution with two arrays
Scanner sc = new Scanner(System.in);
System.out.print("Please enter name of student: ");
String name = sc.nextLine();
for(int i = 0; i < arrayString.length; i++){
if(name.equals(arrayString[i])) {
System.out.println(arrayReal[i]);
}
}
Solution with a HashMap
Initialize HashMap
HashMap<String, Double> hm = new HashMap<String, Double>();
Fill HashMap
hm.put("Christopher Lee", 54.0);
Print double value of student
System.out.print("Please enter name of student: ");
String name = sc.nextLine();
System.out.println(hm.get(name));
Instead of storing into arrays, I would rather tell you to pass the data to data into generic arraylist and then query the result using get() method.
You are making simple thing difficult.
Just use a HashMap with name as the keys and test-score as the values.
You open file
You read each line and translate each line to an entry of hash map
When a text is input to the console, you just get it from hash map, if existed return the value, if not then back to number 3
I am making an app that keeps username and scores from a game in a txt file. The concept is that when it writes a new username and score to the txt file it should open the .txt file, read it and then make a clone of it adding a new uername and score entry in the txt file.
I am thinking of making this with 2 object arrays. The first is the one that is read in and the new will be the one is writen which will have one more entry.
So if player[i] is readen player[i+1] should be writen with new entry.
I am giving u the code below!
private Player[] myplayer=null;
private Player[] mynewplayer=null;
//open Players.txt
int i;
int n;
String filename="players.txt";
try
{
FileReader fp=new FileReader(filename);
BufferedReader bf=new BufferedReader(fp);
n=Integer.parseInt(bf.readLine());
myplayer=new Player[n];
int x=n+1;
mynewplayer=new Player[x];
for(i=0;i<n;i++)
{
String s=bf.readLine();
String user="",score="";
user=s.substring(0,s.indexOf(","));
s=s.substring(s.indexOf(",")+1);
score=s;
myplayer[i]=new Player(user,Double.parseDouble(score));
for(i=0;i<n;i++)
{
mynewplayer[i]= myplayer[i];
}
mynewplayer[x]=new Player(Username,Double.parseDouble(score));
}
bf.close();
fp.close();
}catch(IOException e)
{
System.out.println("Exception was "+e.getMessage());
}
//----------------------------------WRITE mytxt!-------------
n=myplayer.length;
try
{
filename="players.txt";
FileWriter fp=new FileWriter(filename);
fp.write(""+n+"\n");
for(i=0;i<n+1;i++)
fp.write(""+mynewplayer[i]+"\n");
fp.close();
}catch(IOException e)
{
System.out.println("Exception was "+e.getMessage());
}
//----------------------------------WRITE mytxt!-----------
//Get on Message
String s="";
for(i=0;i<mynewplayer.length;i++)
s=s+mynewplayer[i]+"\n";
JOptionPane.showMessageDialog(null,"Players are \n "+s);
Problem is that when it's written, it returns null for mynewplayer.
I suppose the mynewplayer doesnt really take the entries of the "myplayer" but neither writes the new username.
Compile doesnt show any errors. Just writes NULL to the textfile.
Ask me if u want further info on the code writen!
Thanks in advance!
Here is an edited version of your code, with some improvements and there should be a comment around code that I changed, explaining what I did.
Player[] myPlayer = null; // first word uncapitalized, every
Player[] myNewPlayer = null; // other word begins with a capital
//open Players.txt
int i, n; // combine the variables into 1 line
String filename = "players.txt";
try {
FileReader fp = new FileReader(filename);
BufferedReader bf = new BufferedReader(fp);
n = Integer.parseInt(bf.readLine());
// not needed
//myPlayer = new Player[n];
// NOT NEEDED int x = n + 1;
myNewPlayer = new Player[n + 1];
for (i = 0; i < n; i++) {
String s = bf.readLine();
String user, score; // combine variables, doesnt need to initalize them
String[] items = s.split(","); // Splits the line into array elements on every delimiter -> ,
//user = s.substring(0, s.indexOf(","));
//s = s.substring(s.indexOf(",") + 1);
//score = s;
user = items[0];
score = items[1];
// this line below isnt actually needed
//myPlayer[i] = new Player(user, Double.parseDouble(score));
// Create a new player clone, dont copy the previous one
myNewPlayer[i] = new Player(user, Double.parseDouble(score));
}
// We've read all the variables from the text file, now we create the last one
// Since myNewPlayer is (n+1) size, the range of the array is
// 0 to n
// the last index will be n New Score Variable
myNewPlayer[n] = new Player("Username variable", Double.parseDouble("22"));
bf.close();
fp.close();
} catch (IOException e) {
System.out.println("Exception was " + e.getMessage());
}
//----------------------------------WRITE mytxt!-------------
// This is called a ternary operator
// it is a 1 line if statement
// the format is like so
// booleanLogic ? trueAnswer Execution : falseAnswer Execution;
// if () { true }else { false }
n = myNewPlayer != null ? myNewPlayer.length : 0;
// CHANGED HERE - was using the first array rather than second
// dont need the 1st array
try {
filename = "players.txt";
FileWriter fp = new FileWriter(filename);
// Dont need "" before the items
fp.write(n + "\n");
for (i = 0; i < n; i++) {
fp.write(myNewPlayer[i] + "\n");
}
fp.close();
} catch (IOException e) {
System.out.println("Exception was " + e.getMessage());
}
//----------------------------------WRITE mytxt!-----------
//Get on Message
String s = "";
for (i = 0; i < myNewPlayer.length; i++) {
// s += ""; is like doing s = s + "";
s += myNewPlayer[i] + "\n";
}
JOptionPane.showMessageDialog(null, "Players are \n " + s);
I believe that your problem is this:
for(i=0;i<n;i++)
{
String s=bf.readLine();
String user="",score="";
user=s.substring(0,s.indexOf(","));
s=s.substring(s.indexOf(",")+1);
score=s;
myplayer[i]=new Player(user,Double.parseDouble(score));
for(i=0;i<n;i++)
{
mynewplayer[i]= myplayer[i];
}
mynewplayer[x]=new Player(Username,Double.parseDouble(score));
}
You have nested loops, which is fine, but they use the same counter (the variable i ).
So what is happening is the first line of the file is read, and then added to myplayer[0]. However, instead of just also adding it to mynewplayer[0], you start another loop on i. This loop:
for(i=0;i<n;i++)
{
mynewplayer[i]= myplayer[i];
}
is going to copy the first player into mynewplayer[0]...and then null into every other entry (since myplayer only has the firsdt element filled.
The problem is that after that loop completes, i will equal n, so when you get back to the top of the outer loop, the check $i
Perhaps what you should do is this:
for(i=0;i<n;i++)
{
String s=bf.readLine();
String user="",score="";
user=s.substring(0,s.indexOf(","));
s=s.substring(s.indexOf(",")+1);
score=s;
myplayer[i]=new Player(user,Double.parseDouble(score));
mynewplayer[i]= new Player(user,Double.parseDouble(score));
}
mynewplayer[x]=new Player(<the new username>,Double.parseDouble(<the new score>));