Sorry if everyone sees me post a lot of silly questions today (just a preface). However this is the final for a summer class and my teacher stopped caring/explaining how to do things for my first coding class.
For this project I have to print a list of integers from a .dat file into a program in reverse order with a max of 40 possible values in the array (Did all that) The problem I am encountering is that he said the program should also be flexible enough to deal with less than 40 values. However given my current code I always encounter an error saying "nosuchelementexception". Any help would be greatly appreciate. Below is a copy of what I have:
import java.io.*; //Imports any file operation (ie Reading or Writing)
import java.util.Scanner; //Imports scanner class
public class program3
{
public static void main(String [] ars) throws IOException
{
double [] Values; // creating array called value
Values = new double [40]; // establishing array with 40 cells
int k; // creating counter integer
Scanner InputFile = new Scanner( new FileReader("temp.dat")); // input file you wish to open.
for (k = 0 ; k < Values.length ; k++)
Values[k] = InputFile.nextDouble();
for (k = Values.length - 1 ; k >= 0 ; k--)
System.out.println("Cell " + k + " contains the value " + Values[k]);
InputFile.close();
}
}
The problem you are having is that the length attribute of an array refers to the declared length, not the amount of data in it.
When you try to use the length (in this case 40) to control the loop you use for reading data, you will get an error if there are fewer elements to read.
What you want to do is read more input only while there exists more input to get:
int k = 0;
while (inputFile.hasNextDouble()) {
Values[k++] = inputFile.nextDouble();
}
Also, consider using an ArrayList instead of an array. The ArrayList class allows you to store a dynamic amount of data, so you don't have to worry about pre-allocating storage space:
ArrayList<Double> values = new ArrayList<>();
while (inputFile.hasNextDouble()) {
values.add(inputFile.nextDouble());
}
You can use a while loop and a counter
import java.io.*; // Imports any file operation (ie Reading or Writing)
import java.util.Scanner; // Imports scanner class
public class program3
{
public static void main(String [] ars) throws IOException
{
double [] Values; // creating array called Values
Values = new double [40]; // establishing array has 40 cells
int counter = 0; // creating counter integer
Scanner inputFile = new Scanner( new FileReader("temp.dat")); //input file you with to open.
while(inputFile.hasNextDouble()){
Values[counter] = InputFile.nextDouble();
counter++;
}
for (i = counter - 1 ; i >= 0 ; i--)
System.out.println("Cell " + i + " contains the value " + Values[i]);
InputFile.close();
}
}
If you do not have to use an Array, use an ArrayList<Double>. This allows you to call values.add(value) to add to the list. The length is variable and you can use your same code (just replace values[i] with values.get(i))
However, if you do have to use arrays, created a method that adds to the array. Start with a 0 length array, and when an element is added, create a new array of length+1, then copy the old elements in, and add the new element at the end.
There are many other ways to go about this, but these two allow you to use your existing working code.
Array approach:
values = new double[0];
public void add(double x){
double[] temp = new double[values.length +1];
for(int i =0; i< values.lenght; i++){
temp[i] = values[i];
}
temp[temp.length-1] = x;
values = temp;
}
you should use an arrayList instead so you don't have to initially set the size of the array. This would make it so that you never have empty elements in the array.
Another option would be to initialize the array with placeholder values like -1, and then only perform the switch if the value is not -1.
Add a counter that keeps track of how many item you put into the array and use that to determine where to stop when you go to print them out.
Is there 40 elements in your .dat file. If there isnt your code probably gave the exception.
for (k = 0 ; k < Values.length ; k++)
Values[k] = InputFile.nextDouble();
If your .dat file doesn't contain 40 elemennts then value[39] can't be filled in.
An Array has a fixed size after initialising it, so you may want to use dynamic datastructure or instead use a while loop as posted below. I personally would recommend an ArrayList in this case.
You should also use the method
Scanner.hasNext() or in your particular case Scanner.hasNextDouble() Docs
to get any new elements.
So your program would then look like this:
import java.io.*; //Imports any file operation (ie Reading or Writing)
import java.util.Scanner; //Imports scanner class
import java.util.ArrayList;
public class program3
{
public static void main(String [] ars) throws IOException
{
ArrayList<Double> doubles = new ArrayList<Double>();
Scanner inputFile = new Scanner( new FileReader("temp.dat"));
while (inputFile.hasNextDouble()) {
doubles.add(inputFile.nextDouble());
}
inputFile.close();
for (Double value : doubles) {
System.out.println(value);
}
}
}
Java has convenient methods in it's Collections class to allow sorting. You may want to check this out if you haven't already.
I admire your grit getting on Stack Overflow.
To reward you here's your answer.
The first for loop you have iterates over your new, empty array. That would be find except you are RETRIEVING information from the Scanner object, InputFile.
So you should in fact be iterating over that object! Not your array. No shame though. Classic mistake.
Here's my version of your code:
import java.io.FileReader;
import java.io.IOException; //Imports any file operation (ie Reading or Writing)
import java.util.Scanner; //Imports scanner class
public class program3
{
public static void main( String [] ars ) throws IOException
{
double [] Values; // creating array called value
Values = new double [40]; // establishing array has 20 cells
int k; // creating counter integer
//input file you with to open.
Scanner InputFile = new Scanner( new FileReader( "temp.dat" ) );
for ( k = 0; InputFile.hasNextDouble(); k ++ )
Values[k] = InputFile.nextDouble();
for ( k = Values.length - 1; k >= 0; k-- )
System.out.println( "Cell " + k + " contains the value " + Values[k] );
InputFile.close();
}
}
Hope this helps!
Related
package foundations;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class gnfmd {
public static void main(String[] args) throws IOException
{
int[] array = new int[40];
int i = 0;
File file = new File("hello.txt");
if (file.exists())
{
Scanner hello = new Scanner(file);
System.out.println("file found");
while (hello.hasNext() && i < args.length)
{
array [i] = hello.nextInt();
i++;
}
hello.close();
for (int l : array)
{
System.out.println(array[l]);
}
}
else
{
System.out.println("file not found");
}
}
}
I came across this problem during the java course. the exercise requires to extract all the integers from a .txt file and print them using arrays but it kept printing zeros even when I copy it from the model answer. can anyone please tell me where I have mistaken
You are printing System.out.println(array[l]);. You should be printing System.out.println(l);, because l already holds a different integer from array on each iteration of the for (int l : array) loop. So on the first iteration, l will hold the value of array[0], on the second iteration it will hold array[1], etc. That and the fact that you only initialize the first args.length positions of the array are the reasons why it prints zeros, since the default values for all positions of an array of int are zeros, and you aren't assigning any other value to most, if not all, of those positions.
Example:
public class MyClass {
public static void main(String args[]) {
int[] array = {1,25,46,97};
for (int i : array) {
System.out.println(i);
}
}
}
Output:
1
25
46
97
this is my code can i print my array without zero if it is empty?
import java.util.Arrays;
import java.io.*;
public class Stacks{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("what is the size of your stack? :");
int size = Integer.parseInt (br.readLine());
int get = size;
int[] Array = new int[size];
System.out.println("type: push , pop , exit");
System.out.println("remember! you can EXIT anytime");
System.out.println(Arrays.toString(Array));
/*there still a code here but this is just what i needed to show..*/
}
}
please help me.. PS I don't want to import stacks..
Since your not using your Array as an array, but ultimately as a stack, you will not want to use Arrays.toString() which is designed for printing arrays as arrays. You need to write your own method, bearing in mind the stack your creating maybe smaller than the size of the array you're populating.
Without knowing how you're stack is implement, a basic model would be
public static String arrayAsStack(int[] array, int elements_in_stack) {
String out = "[";
for(int i=elements_in_stack-1; i>=0; i--)
out += arrary[i] + " ";
out+="]";
return out;
}
This method of course may not be right, depending on the way you format your stack-array. Note the elements_in_stack should start at 0. Once you get the right implementation of this method for you stack you can just print the results in the natural way.
if you just want your array to be displayed without the zeros you can just use a if statement.
for( int i = 0; i < Array.length; i ++ ){
if( Array[i] != 0 ){
System.out.print( Array[i] + " ");
}
}
This will just iterate through your array and test if the value is zero. If it is not it will display the value, if it is, it disregards it.
instead of using int type i created it using object
import java.util.Arrays;
import java.io.*;
public class Stacks{
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("what is the size of your stack? :");
int size = Integer.parseInt (br.readLine());
int get = size;
Object[] Array = new Object[size];
System.out.println("type: push , pop , exit");
System.out.println("remember! you can EXIT anytime");
/* here i use the code of Ryan*/
for( int i = 0; i < Array.length; i ++ ){
if( Array[i] != null ){
System.out.print( Array[i] + " ");
}
}
/*there still a code here but this is just what i needed to show..*/
}
}
now i can display 0 if I input it..
I am getting the error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 28
at assignment.assgn1.main(assgn1.java:44)
I would be very grateful if someone could point out the error
package assignment;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.opencsv.CSVReader;
import java.io.FileNotFoundException;
public class assgn1 {
public static void main(String[] args) throws IOException
{
try{
CSVReader csvReader = new CSVReader(new FileReader("E:/AviationData.txt"),'\t','\n');
PrintWriter NYreports = new PrintWriter("E:/NYReports.txt");
String [] nextLine;
int x;
int sum=0;
double totalFatal=0;
Integer largest = 0;
Integer smallest = 0;
String [] token = null;
//read first line, but it will not be counted with the rest of the records
nextLine = csvReader.readNext();
//create a map for unique Broad Phase in flight fields
Map<String, Integer> broadPhase = new HashMap <String, Integer>();
//create an array list that will take in integer values of Fatal Injuries
ArrayList <Integer> intList = new ArrayList<Integer>();
while ((nextLine = csvReader.readNext()) !=null){
sum++;
String field = nextLine[0];
//using regex values!
token = field.split("\\s\\|\\s");
//for (String s: token){
//System.out.println(s);
//}
if(token[28].equals(" ")){
broadPhase.put(token[28],0);
}
if(!token[28].equals(" ") && !token[28].equals("")){
broadPhase.put(token[28], 1);
}
//search for Fatal Injury values
if(!token[23].isEmpty()){
x=Integer.parseInt(token[23]);
//add to ArrayList
intList.add(x);
totalFatal = x + totalFatal;
}
if(token[4].contains(", NY") && token[5].contains("/2015")){
NYreports.println(nextLine[0]);
}
}
for(int i =0; i<intList.size()-1; i++){
if (intList.get(i) > largest);
largest = intList.get(i);
if (intList.get(i)< smallest)
smallest = intList.get(i);
}
System.out.println("There are " + sum + " records");
System.out.println("There are " + (broadPhase.size())+" unique values in Broad Phase of Flight");
totalFatal = (totalFatal/sum);
System.out.println(largest + " is the largest number of Fatal injuries");
System.out.println("The average of Fatal injuries is " + totalFatal);
NYreports.close();
csvReader.close();
}
catch (FileNotFoundException ex){
System.out.println("File not Found");
}
}
}
the error is on the line where if(token[28].equals(" ")){. is written.
what can i change to avoid it. also if any change in method used by me can be done.
ArrayIndexOutOfBoundsException generally occurs when you try to access
an index which is not present on the array
, ie.. index > length - 1 (since arrays in java are 0 based).
To avoid this error make sure that you use only valid indexes , which are
0 =< idx < length.
In the current context you may want to add an additional check to ensure that array contains that index along with the normal if conditions.
something like
if(token.length > 28 && token[28].equals(" ")){
broadPhase.put(token[28],0);
}
The error is because token[28] doesn't exist. In other words, your split() call is returning an array that isn't as long as you think it is. I would check your input to see whether or not your input is correct.
On a side note, your method seems to be very... rough and hard coded. Assuming that you know the exact order the tokens are stored in, a better way to do this that would avoid the ArrayIndexOutOfBounds Exception is to loop through your tokens array using a either a for each loop or a normal for loop.
You can then parse each section while you're looping through it.
For example:
for (int i = 0; i < tokens.length; i++) {
// based on the i value, parse a different way
}
The code below is the entire program so far (just to avoid any missing pieces.
The issue I'm having is that I'm trying use the .substring(int,int) method to pull two characters from the given string and write the two characters pulled into a separate array. The problem is that every character pulled from the string using .substring() is a blank space. There are no letters pulled at all. I tested the function using a simple print method and it went to show that printing sentences.get(i).substring(j,j++) only prints blank spaces. It's populating my arrays with those empty spaces.
Any clue as to what could be causing this? My compiler isn't giving me any errors or warnings whatsoever.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class JacSim {
public static void main(String [] args) throws FileNotFoundException {
Scanner userScanner = new Scanner(System.in);
System.out.println("Please enter the filename for your input file (with extension).");
String fileName = userScanner.nextLine();
File file = new File(fileName);
Scanner scanner = new Scanner( new FileInputStream(file));
List<String> sentences = new ArrayList();
while (scanner.hasNextLine()) {
String sentence = scanner.nextLine();
sentences.add(sentence);
}
System.out.println("Input Sentences:\n");
for(int i=0;i<sentences.size();i++) {
System.out.println(i + " : " + sentences.get(i));
}
List<List<String>> shingles = new ArrayList();
sentences.stream().forEach((String _item) -> {
shingles.add(new ArrayList());
});
System.out.println("\nSorted Shingle Arrays:\n");
shinglesMethod(shingles, sentences);
}
private static List shinglesMethod(List<List<String>> shingles, List<String> sentences) {
for (int i=0;i<sentences.size();i++) {
for(int j=0;j++<sentences.get(i).length();j++) {
shingles.get(i).add(sentences.get(i).substring(j,j++));
}
showList( i, shingles.get(i) );
}
return shingles;
}
private static void showList( int n, List List ) {
System.out.print(n + " : ");
List.stream().forEach((o) -> {
System.out.print( o + " " );
});
System.out.println();
}
The chunk of code to pay attention to is
for (int i=0;i<sentences.size();i++) {
for(int j=0;j++<sentences.get(i).length();j++) {
shingles.get(i).add(sentences.get(i).substring(j,j++));
}
showList( i, shingles.get(i) );
}
Forgot to clarify that the scanner is reading in the words properly and that each string is read as expected. The only issue I'm finding is with the .substring() method.
This seems to be rooted in confusion about what ++ does. j++ returns the value of j and afterwards increments j.
.substring(j,j++) will always return the empty string, because it increments j after getting a substring between j inclusive and j exclusive. substring(j, j + 1) would probably be more what you want.
You also need to use j + 1 < sentences.get(i).length(), instead of j++, because you're changing the value of j as you're trying to check it, which is almost certainly not what you want. The only place j++ should be mentioned would be in the update statement in the for loop.
j++ uses the value of j and then increments the value of j. So your code is equivalent to substring(j,j). Also, when you write x.substring(i,j), the substring begins at i and extends to the character at j - 1.
Use substring(j,j+2) instead and change the condition of your inner while loop to j<sentences.get(i).length() - 2.
Edit: I've solved this. I was not properly reading in the second number at the top of the file so I was getting a square array. I solved it by skipping the first number with a scanner.next(). I'll post the corrected code below. Thanks for everyone's help.
I'm trying to learn file i/o and the project has you read a file you create. The file begins with two numbers that are the number of students in a class and the number of projects to be graded and then after that there is a large matrix beginning with names and then scores to be averaged. Something like this:
2 3
John 44.4 55 66.1
Lisa 33 44 55
The completely corrected method (though still needs fine-tuning for exception handling):
public static double[][] getArrays(String fileName, int num1, int num2) {
double[][] twoDArray = new double[num1][num2];
String[] names = new String[num1];
try {
Scanner fileReader = new Scanner(new File(fileName)); //Create a scanner
fileReader.nextLine();
do {
for (int i = 0; i < num1; i++) {
names[i] = fileReader.next();
System.out.println(names[i]);
for (int j = 0; j < twoDArray[0].length; j++) {
twoDArray[i][j] = fileReader.nextDouble();
}
fileReader.nextLine();
}
} while (fileReader.hasNext());
} catch (FileNotFoundException | NoSuchElementException ex) { //Catch any exceptions
System.out.println("Exception caught");
}
return twoDArray;
}// end of get2DArray method
Your question is titled,
read a 2d array from file-Java
But I think that the last thing you want to do here is to create a 2D array, and your code is completely ignoring the student's name.
Instead you should create a Student class, one that has two fields, a String field to hold the student's name, and an ArrayList<Double> or double[], your choice, to hold the grades.
Then put each Student object, which you create on reading in a line of data from the file, into either an ArrayList<Student> or a Student[] array, again your choice.
If you go with arrays (which I'm guessing is your requirement for your class), then pseudo code could be:
create File Scanner object, fileScanner
read line,
create line Scanner with line,
get both ints studentCount and gradeCount, and store in variables.
dispose of line Scanner
Create Student array
??? possibly read an empty line (if your file representation is accurate).
for index goes from 0 to < student count
read line with File Scanner
create line Scanner with line
next token goes into a name String
create 1-D double array
for other index goes from 0 to < gradeCount
use line scanner to get doubles and put into one double array
end for loop
dispose of line scanner
create Student object with name and double array,
place Student object into Student array
end for loop
dispose of file scanner
I believe from looking at your code that you are never actually putting values into the array and due to the fact that when you a print an initialized array that has never had any values associated it will automatically print 0.0
What is causing you not to put any values in the array is your while(fileReader.hasNextDouble()) this is searching for a double next but a string is located there so your while loop isn't happening. (For future reference in debugging adding a simple System.out.println("Hit"); inside your while loop will tell you if you are getting there). There are a couple of changes based on the structure of your txt file that I would do and i have put the code below.
while (fileReader.hasNext()) {
for (int i = 0; i < num1FromFile; i++) {
fileReader.next();
for (int j = 0; j < num2FromFile; j++) {
twoDArray[i][j] = fileReader.nextDouble();
}
}
}
let me know if this works for you!
public static double[][] getArrays(String fileName) throws Exception {
Scanner scanFile = new Scanner(new File(fileName));
int numNames = scanFile.nextInt();
int numScores = scanFile.nextInt();
double[][] scores = new double[numNames][numScores];
String[] names = new String[numNames];
for(int i = 0; i < numNames; i++) {
names[i] = scanFile.next();
for(int j = 0; j < numScores; j++) {
scores[i][j] = scanFile.nextDouble();
}
}
scanFile.close();
return scores;
}
Try to understand the logic before you use it. There might be typo errors in the code above as I am directly typing it in here. The names are read into an array but not used. I believe you are not interested in names, as your method is only returning double[][]. Also I am assuming that the file is perfect, without any comments etc.