Read and Sort a file to array Java - java

I'm attempting to write a program that would read a file "data.txt" which has an undefined amount of numbers in random order, separated by line. It would add these numbers into an array and print out the numbers in one line, each separated by a comma "x, x1". Then on the next line it would print out (in the same format) the list of numbers which has been sorted from smallest to largest size.
Data type is integer.
Currently, I have coded for 3 methods which would allow the array to be sorted (I think they have no error).
I've created another method to read the file and am using a two-step process - once to figure out the number of lines in the file (I ask that this two-step process remain). This method seems to have trouble returning the "lineCount" and apparently I need to make this variable an array (which I find bizarre). How can I fix this code?
You may notice that my method for printing is empty; I have not figured out a way to print the array so that each number is separated by a comma. How do I code for this?
My code so far:
import java.util.*;
import java.io.*;
public class SortAndSearch {
public static void main(String[] args) {
readFile2Array();
printArray();
selectionSort();
printArray();
}
public static void printArray(int[] a) {
}
public static void selectionSort(int[] a) {
int minI = 0;
for (int k = 0; k < a.length - 1; ++k) {
minI = findMinIdx(a, k); // findMinIdx at k-th
swapElement(a, k, minI);// swapElement at k-th
}
}
public static int findMinIdx(int[] a, int k) {
int minIdx = k;
for (int i = k + 1; i < a.length; ++i)
if (a[i] < a[minIdx])
minIdx = i;
return minIdx;
}
public static void swapElement(int[] a, int i, int j) {
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static int[] readFile2Array(String fileName) {
File dat = new File("data.txt");
int lineCount = 0;
int[] a = new int[lineCount];
int i;
try{ Scanner sc = new Scanner(dat);
while (sc.hasNextLine()){ //first read to count -> int lineCount;
lineCount++;
return lineCount; //I have trouble with this line
}
while (sc.hasNextLine()){ //second read to array -> hasNext(),
a[i] = sc.nextInt();
return a;
}
}
catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
e.printStackTrace();
}
}
public static int binarySearch(int[] arr, int val){
int minIdx, maxIdx, index = -1;
while(){ int middleIdx = (minIdx + maxIdx)/2;
if( arr[???] ==val){
index = middleIdx;
break } // update minIdx, maxIdx //if smaller then cut right, if larger then cut left
}
return index; }
}
The last method in the program would attempt to locate the element number of a user inputted number by using this (pseudo)code:
1. Let ‭min = 0‬ and ‭max = n-1‬ (where n is the array’s length)‬‬‬‬
2. If ‭max < min‬, then stop: ‭target‬ is not present in ‭array‬. return ‭false‬.‬‬‬‬‬‬‬‬
3. Compute ‭guess‬ as the average of ‭max‬ and ‭min‬, rounded down (so that it is an integer).‬‬‬‬‬‬
4. If ‭array[guess]‬ equals ‭target‬, then stop. You found it! Return ‭guess‬.‬‬‬‬‬‬
5. If the guess was too low, that is, ‭array[guess] < target‬, then set ‭min = guess + 1‬.‬‬‬‬
6. Otherwise, the guess was too high. Set ‭max = guess - 1‬.‬‬
7. Go back to step 2.
How would I code for this?
I would really appreciate any help in any area of this program!

Managed to fix the first part of the code:
readFile2Array method:
public static int[] readFile2Array(String fileName) {
try {
int lineCount = 0;
Scanner sc = new Scanner(new File("data.txt"));
while (sc.hasNext()) { // first read to count -> int lineCount;
lineCount++; // second read to array -> hasNext(),
sc.nextLine();
}
sc.close();
sc = new Scanner(new File("data.txt"));
int[] x = new int[lineCount];
int n = 0;
while (sc.hasNext()) {
x[n] = Integer.parseInt(sc.nextLine());
n++;
}
sc.close();
return x;
} catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
e.printStackTrace();
}
return null;
}
Print array separated by comma:
public static void printArray(int[] a) {
try {
int lineCount = 0;
Scanner sc = new Scanner(new File("data.txt"));
while (sc.hasNext()) {
lineCount++;
sc.nextLine();
}
sc.close();
for (int i = 0; i < a.length; ++i) {
System.out.print(a[i]);
if (i < lineCount-1) System.out.print(", ");
}
} catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
}
System.out.println();
}
Last method is still a mystery to me though!

I agree with VGR that you haven't actually asked a question, but by reading your code I guess that you were describing what you wanted to achieve...
There are some flaws in your readFile2Array-method, which might solve the problem:
1)
int lineCount = 0;
int[] a = new int[lineCount]; //The size of a will always be 0, so you can't add anything to it, even though you are trying to do this later. Consider using a List instead, as the size of the list can increase dynamically.
2)
while (sc.hasNextLine()){ //first read to count -> int lineCount;
lineCount++;
return lineCount; //I have trouble with this line
}
//The problem is the return type: You method signature states that you will return int[], but here you are trying to return an int.
//It will also just increase lineCount once and try to return this.
3)
//Your scanning will be at the 2nd line because of 2) and not going through the entire file again. To do this you need to create a new instance of Scanner. And the int[] a has a size of 0 at this point.
while (sc.hasNextLine()){ //second read to array -> hasNext(),
a[i] = sc.nextInt();
return a;
}
So in order to solve this you should refactor your code to something like:
public static List<Integer> readFile2Array(String fileName) {
File dat = new File("data.txt");
List<Integer> a = new ArrayList<>();
try{ Scanner sc = new Scanner(dat);
while (sc.hasNextLine()){
a.add(sc.nextInt());
}
sc.close(); //Always remember to close, when done :)
System.out.println("Added " + a.size() + " lines to the list.");
return a;
} catch (FileNotFoundException e) {
System.out.println("File cannot be opened");
e.printStackTrace();
return new ArrayList<>();
}
}
What I changed:
removed the lineCount as this is implicit stored in the size of the list called a.
Changed the int[] a to a List as this always will allow adding elements by increasing its size when needed.
Removed i as was never used, only initialized.
Removed the first while-loop as we don't need to know the amount of lines that is going to be added.
Added a return-statement in the catch-closure. We need to return something (even an empty array or maybe the not-yet-finished array)
I hope this helps. :)

I'm glad you got that part working. :)
To print out the array, it will be best to use whatever data you have of the array. By calling a.length, you don't have to count the number of lines from the input again, which you are not guaranteed are still the same if the input has changed in the mean time.
So this piece of code should do the trick:
public static void printArray(int[] a) {
for (int i = 0; i < a.length; ++i) {
System.out.print(a[i]);
if (i < a.length-1) System.out.print(", ");
}
System.out.println();
}

Related

is there a way to read values from a file int an array and initialize those value?

import java.io.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
File file = new File("C:\\Users\\HIM\\IdeaProjects\\File Tutorial\\src\\quad.txt");
Scanner scanner = new Scanner(file);
double a , b, c;
double[] arr = new double[3];
for(int i = 0; i < arr.length; i++) {
while (scanner.hasNextLine()) {
arr[i] = scanner.nextInt();
System.out.println(arr[i]);
}
}
a = arr[0];
System.out.println(a);
b = arr[1];
System.out.println(b);
c = arr[2];
System.out.println(c);
} catch (Exception e){
System.out.println("Not Found");
}
}
}
i used this code, but from the loop that transferred the values 2, 3, 4, into the array it was read successful but i tried initializing those array values into a,b,c, but it only reads the last value and assign it to a.
You don't say what your input file looks like, so it's hard to tell you exactly what's wrong, but I suspect the issue is you are using hasNextLine in your loop, but nextInt when you read. This won't behave in the way you expect for input like this, for example:
1 2 3
Notice that there is one line, so hasNextLine will return false because, while there are multiple ints, there is only one line.
What you probably want instead is Scanner#hasNextInt
In addition, this logic is probably not correct:
for(int i = 0; i < arr.length; i++) {
while (scanner.hasNextLine()) {
arr[i] = scanner.nextInt();
System.out.println(arr[i]);
}
When a Scanner moves to the next token, you cannot go back. So you can only read from it once without creating a new scanner.
What you likely want is the following:
int i = 0;
while (scanner.hasNextInt()) {
arr[i] = scanner.nextInt();
System.out.println(arr[i]);
i++;
}
This will go through the scanner once and correctly populate your values.
for(int i = 0; i < arr.length; i++) {
while (scanner.hasNextLine()) {
arr[i] = scanner.nextInt();
System.out.println(arr[i]);
}
}
Look at the inner loop. You're running while(scanner.hasNextLiine() however i is never getting iterated while you read the file. As a result, you read the entire file, but always put it into arr[i=0].
A better solution may be
int i = 0;
while(scanner.hasNextLine() && i < arr.length){
arr[i++] = scanner.nextInt();
}
Which will combine the functionality of your while and for loop. Another alternative:
for(int i = 0; i < arr.length && scanner.hasNextLine(); i++){
arr[i] = scanner.nextInt();
}
Chris's answer is also valid. nextInt and hasNextLine aren't the same thing. But in this case I'm assuming your file has ints on every line.

Java: Most Efficient Way to Get Input Integer Array

I'm working on a problem that requires me to store a very large amount of integers into an integer array. The input is formatted so that one line displays the amount of integers and the next displays all of the values meant to be stored. Ex:
3
12 45 67
In the problem there is closer to 100,000 integers to be stored. Currently I am using this method of storing the integers:
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] iVau = new int[n];
String[] temp = scanner.nextLine().split(" ");
for(int i = 0; i < n; i++) {
iVau[i] = Integer.parseInt(temp[i]);
}
This works fine, however the problem I am solving has a strict time limit and my current solution is exceeding it. I know that there is a more efficient way to store this input using buffered readers and input streams, but I don't know how to do it, can someone please show me.
The way you are using Scanner makes your program save a String containing the whole numbers at once, in memory. With 100000 numbers in the 2nd line of your input, it is not so efficient, you could read numbers one after the other without keeping the previous one in memory. So, this way, avoiding using Scanner.readLine() should make your program run faster. You will not have to read the whole line one time, and read a 2nd time this String to parse the integers from it: you will do both of these operations only once.
Here is an example. The method testing() does not use any Scanner. The method testing2() is the one you provided. The file tst.txt contains 100000 numbers. The output from this program, on my Mac Mini (Intel Core i5#2.6GHz) is:
duration without reading one line at a time, without using a Scanner instance: 140 ms
duration when reading one line at a time with a Scanner instance: 198 ms
As you can see, not using Scanner makes your program 41% faster (integer part of (198-140)/140*100 equals 41).
package test1;
import java.io.*;
import java.util.*;
public class Test {
// Read and parse an Int from the stream: 2 operations at once
private static int readInt(InputStreamReader ir) throws IOException {
StringBuffer str = new StringBuffer();
int c;
do { c = ir.read(); } while (c < '0' || c > '9');
do {
str.append(Character.toString((char) c));
c = ir.read();
} while (!(c < '0' || c > '9'));
return Integer.parseInt(str.toString());
}
// Parsing the input step by step
private static void testing(File f) throws IOException {
InputStreamReader ir = new InputStreamReader(new BufferedInputStream(new FileInputStream(f)));
int n = readInt(ir);
int [] iVau = new int[n];
for (int i = 0; i < n; i++) iVau[i] = readInt(ir);
ir.close();
}
// Your code
private static void testing2(File f) throws IOException {
Scanner scanner = new Scanner(f);
int n = scanner.nextInt();
int[] iVau = new int[n];
scanner.nextLine();
String[] temp = scanner.nextLine().split(" ");
for(int i = 0; i < n; i++)
iVau[i] = Integer.parseInt(temp[i]);
scanner.close();
}
// Compare durations
public static void main(String[] args) throws IOException {
File f = new File("/tmp/tst.txt");
// My proposal
long t = System.currentTimeMillis();
testing(f);
System.out.println("duration without reading one line at a time, without using a Scanner instance: " + (System.currentTimeMillis() - t) + " ms");
// Your code
t = System.currentTimeMillis();
testing2(f);
System.out.println("duration when reading one line at a time with a Scanner instance: " + (System.currentTimeMillis() - t) + " ms");
}
}
NOTE: creating the input file is done this way, with bash or zsh:
echo 100000 > /tmp/tst.txt
for i in {1..100000}
do
echo -n $i" " >> /tmp/tst.txt
done
I believe this is what you're looking for. A BufferedReader can only read a line at a time, so it is necessary to split the line and cast Strings to ints.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n];
String[] line = br.readLine().split(" ");
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(line[i]);
}
} catch (IOException e) {
e.getStackTrace();
}
Just a thought, String.split returns an array of Strings. You say the input can be around 100,000 values. So in order to split the array in this way, String.split must be iterating through each element. Now in parsing the new array of strings to Integers you have iterated through the collection twice. You could do this in one iteration with a few small tweaks.
Scanner scanner = new Scanner(System.in);
String tmp = scanner.nextLine();
scanner = new Scanner(tmp);
for(int i = 0; scanner.hasNextInt(); i++) {
arr[i] = scanner.nextInt();
}
The reason for linking the scanner to a String instead of leaving it on System.in is so that it ends properly. It doesn't open System.in for user input on the last token. I believe in big O notation this is the difference between O(n) and O(2n) where the original snippet is O(2n)
I am not quite sure why OP has to use Integer.parseInt(s) here since Scanner can just do the parsing directly by new Scanner(File source).
Here is a demo/test for this idea:
public class NextInt {
public static void main(String... args) {
prepareInputFile(1000, 500); // create 1_000 arrays which each contains 500 numbers;
Timer.timer(() -> readFromFile(), 20, "NextInt"); // read from the file 20 times using Scanner.nextInt();
Timer.timer(() -> readTest(), 20, "Split"); // read from the file 20 times using split() and Integer.parseInt();
}
private static void readTest() {
Path inputPath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/main/java/io/input.txt"));
try (Scanner scanner = new Scanner(new File(inputPath.toString()))) {
int n = Integer.valueOf(scanner.nextLine());
int[] iVau = new int[n];
String[] temp = scanner.nextLine().split(" ");
for (int i = 0; i < n; i++) {
iVau[i] = Integer.parseInt(temp[i]);
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void readFromFile() {
Path inputPath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/main/java/io/input.txt"));
try (Scanner scanner = new Scanner(new File(inputPath.toString()))) {
while (scanner.hasNextInt()) {
int arrSize = scanner.nextInt();
int[] arr = new int[arrSize];
for (int i = 0; i < arrSize; ++i) {
arr[i] = scanner.nextInt();
}
// System.out.println(Arrays.toString(arr));
}
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
private static void prepareInputFile(int arrCount, int arrSize) {
Path outputPath = Paths.get(Paths.get("").toAbsolutePath().toString().concat("/src/main/java/io/input.txt"));
List<String> lines = new ArrayList<>();
for (int i = 0; i < arrCount; ++i) {
int[] arr = new int[arrSize];
for (int j = 0; j < arrSize; ++j) {
arr[j] = new Random().nextInt();
}
lines.add(String.valueOf(arrSize));
lines.add(Arrays.stream(arr).mapToObj(String::valueOf).collect(Collectors.joining(" ")));
}
try {
Files.write(outputPath, lines);
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
}
Locally tested it with 1_000 arrays while each array has 500 numbers, reading all the elements cost about: 340ms using Scanner.nextInt() while OP's method about 1.5ms.
NextInt: LongSummaryStatistics{count=20, sum=6793762162, min=315793916, average=339688108.100000, max=618922475}
Split: LongSummaryStatistics{count=20, sum=26073528, min=740860, average=1303676.400000, max=5724370}
So I really have doubt the issue lies in the input reading.
Since in your case you are aware of the total count of elements all that you have to do is to read X integers from the second line. Here is an example:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int count = in.nextInt();
int array[] = new int[count];
for (int i = 0; i < count; i++) {
array[i] = in.nextInt();
}
}
If this is not fast enough, which I doubt, then you could switch to the use of a BufferedReader as follows:
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int count = Integer.parseInt(in.readLine());
int array[] = new int[count];
for (int i = 0; i < count; i++) {
int nextInteger = 0;
int nextChar = in.read();
do {
nextInteger = nextInteger * 10 + (nextChar - '0');
nextChar = in.read();
} while (nextChar != -1 && nextChar != (int)' ');
array[i] = nextInteger;
}
}
In your case the input will be aways valid so this means that each of the integers will be separated by a single whitespace and the input will end up with EoF character.
If both are still slow enough for you then you could keep looking for more articles about Reading Integers in Java, Competative programming like this one: https://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/
Still my favorite language when it comes to competitions will always be C :) Good luck and enjoy!

How to remove an element from an array

In Java, The teacher taught us how to remove an element from an array without using array utils and so on. So I tried the method he gave to us. It updates the index value exactly as I want. after it changes the index value, I want it to delete the last index, "sizeOfArray-1"
but I couldn't do that! Any help?
Here the code:
import java.util.Scanner;
public class Arrays {
static int x[] = { 1, 2, 3, 4, 5, 6, 7 };
static Scanner input = new Scanner(System.in);
public int search(int target) {
for (int index = 0; index < x.length; index++) {
if (x[index] == target)
return index;
}
return -1;
}
public void deleteIndex(int target) {
int deleted = search(target);
if (deleted == -1)
System.out.println("Entry Not Found!");
else {
x[target] = x[7-1];
}
}
public static void main(String[] args) {
Arrays f = new Arrays();
int counteri = 0;
int counterj = 0;
for (int j = 0; j < x.length; j++) {
System.out.print(counterj + "=>" + x[j] + " \n");
counterj++;
}
f.deleteIndex(input.nextInt());
for (int i = 0; i < x.length; i++) {
System.out.print(counteri + "=>" + x[i] + " \n");
counteri++;
}
}
}
First of all you have to change this line
x[target] = x[7-1];
to this :
x[deleted] = x[7-1];
because you find an element in your search function, and return its index to deleted so you have to do your action in x[deleted] not x[target]
Your code just replace the actual value of element with amount of last element in here :
else {
x[target] = x[7-1];
}
So when you want to (so as you call it) delete the last element it just replace last element with it self so it didnot do anything.
You can just simply assign another value that doesnt exist in your array for instance -1 and you could see your function works as you want.
a thing like this :
else {
x[deleted] = -1;
}
But it is not delete actually, and you cant delete items of array in java.
You really cannot delete an item from an array in Java. Here is some pseudo code that shows what you can do instead:
create a new array that has size -1 of the original array
start looping, keep track of the current index
copy the item(s) from the original array to the new array corresponding to the current index if it should be kept (otherwise skip the item that should be removed)
return the new array
An array in Java has fixed predefined length, once you initialize the array you cannot actually remove an element from it. The best thing you can do is to create another array containing all the elements of the original array without that specific one.
//delete the element the perticular element in a position//
import java.util.*;
class main13
{
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
System.out.println("Enter the range");
int no=sc.nextInt();
System.out.println("Enter the array elements");
int a[]=new int[no];
int i,j;
for(i=0;i<no;i++)
{
a[i]=sc.nextInt();
}
System.out.println("Enter the element you want to delete");
int d=sc.nextInt();
for(i=0;i<no;i++)
{
if(d==a[i])
{
for(j=i;j<no-1;j++)
{
a[j]=a[j+1];
}
break;
}
else
{
System.out.println("Element not found");
System.exit(0);
}
}
System.out.println("After deletion:");
for(i=0;i<no-1;i++)
{
System.out.println(a[i]);
}
}
}

Convert array elements from string to an integer

I'm trying to count up the values stored in an array, here is my code:
public void printScores()
{
String sep = ":";
File inputfile = new File ("P:/SD/Assignment1/fbScores.txt");
String [] stringArr;
String line = "";
try {
Scanner filescan = new Scanner(inputfile);
while(filescan.hasNext())
{
line = filescan.nextLine();
stringArr = line.split(sep);
if(stringArr.length == 4)
{
System.out.println(stringArr[0]+"\t [" +stringArr[2]+"]\t|" + stringArr[1]+"\t["+ stringArr[3]+" ]\n");
}
else
{
throw new IllegalArgumentException("String " + line + " does not contain " + sep);
}
}
filescan.close();
}
catch (FileNotFoundException e)
{
System.out.println("problem " +e.getMessage());
}
}
public void totalGoals()
{
int count;
for (int i = 0; i<stringArr.length; i++)
{
//int num[i] = Integer.parseInt(stringArr);
}
}
}
Basically I only want to add the numbers up that are stored in [2] and [3], my totalGoals method at the bottom is where I started, but can't figure out how to change from a string to an integer, any help would be much appreciated!
UPDATE:
public void totalGoals()
{
int[] num = new int[stringArr.length];
int count = 0;
for (int i = 0; i<stringArr.length; i++)
{
num[i] = Integer.parseInt(stringArr[i]);
count = count + num[i];
System.out.println(count);
}
}
You want to parse each string individually - you seem to be trying to do the whole array
int[] num = new int[stringArr.length]; //don't forget to declare your num[] array
for (int i = 0; i<stringArr.length; i++)
{
num[i] = Integer.parseInt(stringArr[i]); // stringArr[i] instead of stringArr
}
Note what this code is actually doing when you break it out of the for loop format.
int[] num = new int[4];
num[0] = Integer.parseInt(stringArr[0]); //the for loop is starting at 0 and stopping
num[1] = Integer.parseInt(stringArr[1]); //when it hits 4
num[2] = Integer.parseInt(stringArr[2]);
num[3] = Integer.parseInt(stringArr[3]);
In truth, you only need 2 and 3.. and all you need to do is add them together. You already have a count variable you could use instead of num
So lets say you only want to loop through 2 and 3... look at the for loop
for (int i = 0; i < stringArr.length; i++)
int i = 0 //your loop is starting at 0
i < stringArr.length; //its ending when i is the array's length (should be 4 judging by your other code)
i++ // i increases by 1 at the end of each time through
So if 0 and 1 are useless, try using int i = 2
You have a count variable. Maybe it should start at 0.. and rather than setting the num variable, you could add the value to your count variable.
About your method.. By itself it should be working.
I'm also not sure which line is line 73
If it is the first line: int[] num = new int[stringArr.length]; Then either your stringArr doesn't exist (for this method) or your stringArr isn't initialized (again, for this method)
Looking at the code you've shown me, I'm guessing the problem is on that first line.
public void printScores() {
//other code
String[] stringArr;
//other code
}
public void totalGoals() {
int[] num = new int[stringArr.length];
int count = 0;
for (int i = 0; i<stringArr.length; i++)
{
num[i] = Integer.parseInt(stringArr[i]);
count = count + num[i];
System.out.println(count);
}
}
Done simply like this, you wouldn't even be able to compile. stringArr would not exist for totalGoals. The two methods are separate and cannot "see" each other's variables.
If you have your code like below - then you are declaring stringArr twice and you have two separate variables named the same thing!
{
String[] stringArr; //This is what totalGoals would be using - it is never assigned
public void printScores() {
String[] stringArr; //This one is used and assigned within printScores
//but totalGoals cannot see/use it
}
public void totalGoals() {
}
}
Use Integer.parseInt(String s) or Integer.parseInt(String s, int radix) to convert your Strings to Integers or primitive ints.
For instance:
try {
String s = "42";
int i = Integer.parseInt(s);
}
catch (NumberFormatException nfe) {
nfe.printStackTrace();
}
You can also use Scanner.nextInt if that suits your context better.
Use integer.parseint to parse string to int
if(stringArr.length == 4)
{
for(int i=0;i<stringArr.length;i++)
{
int c = Integer.parseInt(stringArr[2])+ Integer.parseInt(stringArr[3]);
}
}

Read text file for integers and storing to array using scanner and exceptions

I'm trying to loop through a text file for integers and store integers found into an array.
Using a try-catch to determine which words are integers and which are not using InputMismatchException, removing the non-int strings from the input stream. As well as a NoSuchElementException for blank lines in the file.
My main issue is storing the integers and printing those integers in the array, in my second method :o . It also appears my loop is also recording non-ints as null as well. They aren't suppose be stored into the array.
public static void main(String[] commandlineArgument) {
Integer[] array = ReadFile6.readFileReturnIntegers(commandlineArgument[0]);
ReadFile6.printArrayAndIntegerCount(array, commandlineArgument[0]);
}
public static Integer[] readFileReturnIntegers(String filename) {
Integer[] array = new Integer[1000];
// 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) {
// loop through file for integers and store in array
while (inputFile.hasNextLine()) {
for(int i = 0; i<array.length; i++)
{
try{
array[i] = inputFile.nextInt();
}
catch(InputMismatchException excep1)
{
String word = inputFile.next();
}
catch(NoSuchElementException excep2){
}
}
}
}
return array;
}
public static void printArrayAndIntegerCount(Integer[] array, String filename) {
//prints number of integers from file
//prints each integer in array
}
}
The approach taken in the first method is a bit flawed, since you're incrementing the i variable whether or not an integer is read.
So for example, if the file looked like this:
4
Hello
5
e
7
The beginning of your array would look like
[4, null, 5, null, 7...]
So you will end up with an array of size 1000, which has nulls at unpredictable places in there.
A slightly better approach would be this:
Keep a separate count variable that says how many integers you actually read.
Add items to the array at index count and not at i (since i just says how many lines you've looked at, whereas count will tell you how many integers you've come across).
When you're finished reading them, either
pass the count variable to the method that prints the array (so it knows only to look at the first count items), or
just copy the entire array into a new array of size count.
Example incorporating this into your code:
if(inputFile != null) {
// the number of integers we've read so far
int count = 0;
// loop through file for integers and store in array
while(inputFile.hasNextLine()) {
for(int i = 0; i < array.length; i++) {
try {
array[count] = inputFile.nextInt();
count++;
} catch(InputMismatchException excep1) {
String word = inputFile.next();
} catch(NoSuchElementException excep2) {
}
}
}
}
Then to copy into a correctly sized array,
Integer[] newArray = new Integer[count];
for(int i = 0; i < count; i++) {
newArray[i] = array[i];
}
and just return newArray instead of array.
Your print method will then simply have the same signature and functionality you'd expect:
public static void printArrayAndIntegerCount(Integer[] array, String filename) {
for(int i = 0; i < array.length; i++) {
// print the number at array[i], and whatever else you want to print
}
}
This is probably the better approach, as you can still keep all the method signatures the same, and don't need to mess around with returning multiple variables or changing global state.
Or alternatively, if you don't want to copy the relevant bits into a new array, then you could just pass the count variable somehow to your second method, and do something like
for(int i = 0; i < count; i++) {
System.out.println("\tindex = " + i + ", element = " + array[i]);
}
Key difference there is you're iterating up to count, and not up to array.length.
You would need to find a way to return that from your first method along with the array (or maybe set a static variable somewhere), and you would then need to change the signature of your second method to be
public static void printArrayAndIntegerCount(Integer[] array, int count, String filename) {
...
}
Assuming all you logic for reading integers from file are correct and also hoping this is kind of home work. Though the following implementation is not the right approach, it just solves your purpose. All we are doing here is iterating all the elements in the array until it reaches the null and keep writing them into a buffer.
public static void printArrayAndIntegerCount(Integer[] array, String filename) {
StringBuilder sb = new StringBuilder();
int count = 0;
for(Integer i : array) {
if(i != null) {
count++;
sb.append("index = ").append(i).append(", element = ").append(array[i]).append("\n");
} else {
break;
}
}
System.out.println("number of integers in file \""+filename+"\" = "+count);
System.out.println(sb);
}
Replace your catch statement with:
catch(InputMismatchException excep1)
{
String word = inputFile.next();
i-=1;
}
You were incrementing the array counter if it found a word. I have run my own test and this worked for me to fix your issue.
public static void printArrayAndIntegerCount(Integer[] array, String filename) {
String message = "";
int i = 0;
while(i < array.length && array[i]!=null){
message = message + "index = "+i+", element = "+array[i]+"\n";
i+=1;
}
System.out.println("number of integers in file \""+filename+"\" = "+i);
System.out.println(message);
}

Categories