I'm reading from a file and copying that into an array. My file has five lines of text, a sentence each. I get my output "Array size is 5" but nothing after that. If I do add a print line of the array, it gives me 5 nulls...
Can someone help explain what I did wrong? Thanks!
public static int buildArray() throws Exception
{
System.out.println("BuildArray is starting ");
java.io.File textFile; // declares a variable of type File
textFile = new java.io.File ("textFile.txt"); //reserves the memory
Scanner input = null;
try
{
input = new Scanner(textFile);
}
catch (Exception ex)
{
System.out.println("Exception in method");
System.exit(0);
}
int arraySize = 0;
while(input.hasNextLine())
{
arraySize = arraySize + 1;
if (input.nextLine() == null)
break;
}
System.out.println("Array size is " + arraySize);
// Move the lines into the array
String[] linesInRAM = new String[arraySize];// reserve the memory
int count = 0;
if (input.hasNextLine())
{
while(count < arraySize)
{
System.out.println("test");
linesInRAM[count] = input.nextLine();
System.out.println(linesInRAM[count]);
count = count + 1;
}
}
In this code
int count = 0;
if (input.hasNextLine())
The above hasNextLine will always be false as you have already read all the way through the file.
Either reset the scanner to the beginning of the file, or use a dynamic list e.g. ArrayList to add the elements to.
My Java is a bit rusty, but the basic gist of my answer is that you should create a new Scanner object so that it reads from the beginning of the file again. This is the easiest way to "reset" to the beginning.
Your code is currently not working because when you call input.nextLine() you're actually incrementing the scanner, and thus at the end of that first while() loop input is sitting at the end of the file, so when you call input.nextLine() again it returns null.
Scanner newScanner = new Scanner(textFile);
Then in the bottom of your code, your loop should look like this instead:
if (newScanner.hasNextLine())
{
while(count < arraySize)
{
System.out.println("test");
linesInRAM[count] = newScanner.nextLine();
System.out.println(linesInRAM[count]);
count = count + 1;
}
}
Related
I am struggling to use scanner class to read in a text file while skipping the blank lines.
Any suggestions?
Scanner sc = new Scanner(new BufferedReader(new FileReader("training2.txt")));
trainingData = new double[48][2];
while(sc.hasNextLine()) {
for (int i=0; i<trainingData.length; i++) {
String[] line = sc.nextLine().trim().split(" ");
if(line.length==0)
{
sc.nextLine();
}else{
for (int j=0; j<line.length; j++) {
trainingData[i][j] = Double.parseDouble(line[j]);
}
}
}
}
if(sc.hasNextLine())
{
sc.nextLine();
}
sc.close();
I am currently trying to get it working like this. But it is not working
Scanner sc = new Scanner(new BufferedReader(new FileReader("training.txt")));
trainingData = new double[48][2];
while(sc.hasNextLine()) {
String line = sc.nextLine().trim();
if(line.length()!=0)
{
for (int i=0; i<trainingData.length; i++) {
String[] line2 = sc.nextLine().trim().split(" ");
for (int j=0; j<line2.length; j++) {
trainingData[i][j] = Double.parseDouble(line2[j]);
}
}
}
}
return trainingData;
while(sc.hasNextLine()) {
for (int i=0; i<trainingData.length; i++) {
String[] line = sc.nextLine().trim().split(" ");
You can't just check the scanner once to see if it has data and then use a loop to read the lines of data. You can't assume that you have 48 lines of data just because you define your array to hold 48 lines of data.
You need to go back to the basics and learn how to read data from a file one line at a time and then you process that data.
Here is a simple example to get you started:
import java.util.*;
public class ScannerTest2
{
public static void main(String args[])
throws Exception
{
String data = "1 2\n\n3 4\n\n5 6\n7 8";
// First attempt
System.out.println("Display All Lines");
Scanner s = new Scanner( data );
while (s.hasNextLine())
{
String line = s.nextLine();
System.out.println( line );
}
// Second attempt
System.out.println("Display non blank lines");
s = new Scanner( data );
while (s.hasNextLine())
{
String line = s.nextLine();
if (line.length() != 0)
{
System.out.println( line );
}
}
// Final attempt
String[][] values = new String[5][2];
int row = 0;
System.out.println("Add data to 2D Array");
s = new Scanner( data );
while (s.hasNextLine())
{
String line = s.nextLine();
if (line.length() != 0)
{
String[] digits = line.split(" ");
values[row] = digits;
row++;
}
}
for (int i = 0; i < values.length; i++)
System.out.println( Arrays.asList(values[i]) );
}
}
The example uses a String variable to simulate data from a file.
The first block of code is how you simply read all lines of data from the file. The logic simply:
invokes the hasNextLine() method so see if there is data
invokes the nextLine() method to get the line of data
display the data that was read
repeats steps 1-3 until there is no data.
Then next block of code simply adds an "if condition" so that you only display non-blank data.
Finally the 3rd block of code is closer to what you want. As it reads each line of data, it splits the data into an array and then adds this array to the 2D array.
This is the part of code you will need to change. You will need to convert the String array to an double array before adding it to your 2D array. So change this code first to get it working. Then once this works make the necessary changes to your real application once you understand the concept.
Note in my code how the last row displays [null, null]. This is why it is not a good idea to use arrays because you never know how big the array should be. If you have less that 5 you get the null values. If you have more than 5 you will get an out of bounds exception.
Try adding this to your code:
sc.skip("(\r\n)");
It will ignore blank lines. For More information: Scanner.skip()
I have a text file "names" which contains 10 names, each name on its own line. What I want to do is put these names into an array "anArray". Just to check that I'm doing an alright job, I outputted a line as you can see.
Here's the code I used to try to do that:
public static void main(String[] args) throws FileNotFoundException
{
File file=new File("names.txt");
Scanner my_input= new Scanner(file);
String [] anArray;
anArray = new String[10];
String a = my_input.nextLine();
while(my_input.hasNextLine())
{
for(int i = 0; i<10;i++)
{
while (!(a.equals("\n")))
{
anArray[i] = a;
System.out.println("Element" + i + "of the array is: " + anArray[i]);
}
i++;
a=my_input.next();
}
}
my_input.close();
}
However this code fails, what happens is "Element 0 of the array is: name 1" is outputted an infinite amount of times, "name 1" being the first name in the text file. I don't know what I'm doing wrong here, could anybody enlighten me?
You currently have an infinite loop on your inner while loop, you don't update a so that will loop forever once entered. I think you wanted to check that i is less than 10 and your input still has more lines. You can do that with a singe loop. I would also prefer a try-with-resources over explicitly closing. And you can guard against empty lines with String.isEmpty(). Something like,
File file = new File("names.txt");
try (Scanner my_input = new Scanner(file)) {
String[] anArray = new String[10];
for (int i = 0; i < 10 && my_input.hasNextLine(); i++) {
String line = my_input.nextLine();
if (line.isEmpty()) {
continue;
}
anArray[i] = line;
System.out.printf("Element %d of the array is: %s%n", i, anArray[i]);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
The condition in the innermost while loop never changes, so the contents will repeat indefinitely.
Something to change the value of the phrase
while (!(a.equals("\n")))
must occur in the body of the loop, otherwise it will stay true if it starts out true.
I'm trying to read a 2D array into a file. On compiling, it says that readFile, the Scanner variable may be uninitialized (which I know is because the initialization is in the try catch blocks). When I set readFile to null, however, it manages to count the number of lines but skips everything else.
Do I need to close and remake the scanner and file stuff for the actual reading in of the data? Or is there another error that I'm missing somewhere?
Also, I'm aware that the code for the actual reading in of the 2d array isn't done in the code sample below, but I'm trying to make sure it reads in correctly before I do anything else.
//2D table example I'm trying to read in
0 1 1 0
1 0 0 0
1 0 0 1
0 0 1 0
boolean[][] relationTable;
Scanner keyboard = new Scanner(System.in);
String fileName;
File relationFile;
Scanner readFile;
boolean error = false;
System.out.print("Please enter the name of the table file: ");
do{
fileName = keyboard.next();
try
{
relationFile = new File(fileName);
readFile = new Scanner(relationFile);
error = false;
}
catch(FileNotFoundException fnfe)
{
System.out.println("File was not found. Please enter a new file name:");
error = true;
}
}while (error == true);
//finds number of lines correctly
int count = 0;
while (readFile.hasNextLine())
{
count++;
readFile.nextLine(); //notes the error here when not initialized
}
System.out.println(count); //using the example table above it prints out 4
relationTable = new boolean[count][count];
int i = 0, j = 0, temp = 0;
//doesn't appear to do this section at all.
String[] lines= new String[count];
while (readFile.hasNextLine())
{
lines[i] = readFile.nextLine();
System.out.println(lines[i]);
i++;
}
// finds number of lines correctly
int count = 0;
List<String> lines = new ArrayList<String>();// use arrayList instead of arrays if you dont know the number of lines like we have here.
while (readFile.hasNextLine()) {
count++;
lines.add(readFile.nextLine()); // notes the error here when not
// initialized
}
System.out.println(count); // using the example table above it prints
// out 4
relationTable = new boolean[count][count];
int i = 0, j = 0, temp = 0;
your mistake here is that you were looping using readFile.hasNextLine() but the file was already read and readFile.hasNextLine() always returned false
// here is a loop that works even though its not needed, we could have added the print statement in the loop above.
for (int x = 0; x < count; x++) {
System.out.println(lines.get(x));
}
The problem is that you're already gone through all the lines in the file.
while (readFile.hasNextLine())
{
count++;
readFile.nextLine(); //notes the error here when not initialized
}
After this point, your readFile object has not more lines left. So when you reach
String[] lines= new String[count];
while (readFile.hasNextLine())
{
lines[i] = readFile.nextLine();
System.out.println(lines[i]);
i++;
}
There are not lines left. So in order to solve your problem you have to read the file again before the second while.
relationFile = new File(fileName);
readFile = new Scanner(relationFile);
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);
}
I Really would appreciate it if someone can help me with this. I am trying to do external sorting and I am stuck on the part of merging. I get how I should merge it just not sure what function to use.
Right now I am trying to read in the first words of multiple small text files and store them in a string array of the size of the amount of files. So basically I will have a string array of the first word of each file. Then I determine which one is the smallest alphabetically wise and write that to a new file, after that I would read the next word of the file of that smallest word. This word would be placed in the position of the smallest word that got outputted in string array and compare it to the rest of the first word from the other file. This will keep repeating till all words are sorted.
The main problem I am running into is the fact that I was using scanner and after the first run of comparing it cant switch the smallest word with the next word in the file because scanner don't keep a point of what it has read. I know readline do but since my files are all words separated by only a white space I can't use readline. Can someone please guide me to a sufficient reading function that can't help me solve this problem.
for (int i = 0; i<B;i++)
{
try
{
BufferedReader ins = new BufferedReader(new FileReader(Run-"+ i + ".txt"));
Scanner scanner2 = new Scanner(ins);
temp3[i] = scanner2.next();
System.out.println(temp3[i]);
}
catch(IOException e)
{
}
}
for(int i=0;i<N;i++)
{
String smallest = temp3[0];
int smallestfile = 0;
for(j=0;j<B;j++)
{
int comparisonResult = smallest.compareTo(temp3[j]);
if(comparisonResult>0)
{
smallest = temp3[j];
smallestfile = j;
}
}
BufferedReader ins = new BufferedReader(new FileReader("C:/Run-"+ smallestfile + ".txt"));
Scanner scanner2 = new Scanner(ins);
if(scanner2.hasNext())
{
temp3[smallestfile]=scanner2.next();
}
}
}
catch(Exception e)
{
}
If the files are small enough read the entire file to memory, and use String.split() to separate the strings in arrays and do your magic.
If the the files are bigger, keep then open and read each byte until you find and space, then do it for all the files, compare the strings, do your magic and repeat until all the files reach the end.
EDIT :
how to read the files with BufferedReader
how to split the lines with String.split()
String line = readeOneLineFromTheCurrentFile();
String[] words = line.split(" ");
As for temporarily sorting/storing the words, use a PriorityQueue (not an array). Sorry, I'm too busy watching baseball to add more.
I'm not sure, if I understood you right, but a Scanner does keep the position in a file. You need just as many of them as there are files
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class so {
// returns the index of the smallest word
// returns -1 if there are no more words
private static int smallest(String[] words) {
int min = -1;
for (int i = 0; i < words.length; ++i)
if (words[i] != null) {
if (min == -1 || words[i].compareTo(words[min]) < 0)
min = i;
}
return min;
}
public static void main(String[] args) throws FileNotFoundException {
// open all files
Scanner[] files = new Scanner[args.length];
for (int i = 0; i < args.length; ++i) {
File f = new File(args[i]);
files[i] = new Scanner(f);
}
// initialize first words
String[] first = new String[args.length];
for (int i = 0; i < args.length; ++i)
first[i] = files[i].next();
// compare words and read following words from scanners
int min = smallest(first);
while (min >= 0) {
System.out.println(first[min]);
if (files[min].hasNext()) {
first[min] = files[min].next();
} else {
first[min] = null;
files[min].close();
files[min] = null;
}
min = smallest(first);
}
}
}
Tested with
a.txt: a d g j
b.txt: b e h k m
c.txt: c f i
Update:
In your example, you open and close the file inside the outer for loop. When you reopen a file the next time, it starts at the beginning of the file, of course.
To prevent this, you must keep the file open and move the scanner2 variable and its initialization in front of the outer for loop. You also need multiple Scanner variables, i.e. an array, to keep multiple files open simultaneously.