Array Reading problems - java

Good day . I've the following portions of code which i'm struggling to make work . i've a text file with questions and it is structured in the way that each question inside the text file occupy 10 lines but i want just to display the 6 first lines out of each question then hide the remaining .
my questions in the texfile look like :
Collections
Which of these is not an example of a "real-life" collection?
a. The cards you hold in a card game.
b. Your favorite songs stored in your computer.
c. The players on a soccer team.
d. The number of pages in a book.
d. /// answer
Multithreading
Indefinite postponement is often referred to as __________.
a. deadlock.
b. indigestion.
c. starvation.
d. None of the above.
c. /// answer
basically it has just to display the questions but not the answer . that's what i want to achieve so far .
Any help will be appreciated .
File filing = new File(file);
pattern.setFileName(filing.getAbsolutePath());
if(filing.getAbsoluteFile().exists())
{
try{
ReadFile myFile = new ReadFile(pattern.getFileName());
String[ ] aryLines = myFile.OpenFile( );
int i;
for ( i=0; i < aryLines.length; i++ )
{
System.out.println( aryLines[ i ] ) ;
if(i == 6)
i = i+3;
}
ReadFile class
import java.io.IOException;
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ReadFile
{
private String path;
///////////// set file name
public ReadFile(String filePath)
{
path = filePath;
}
public String[] OpenFile() throws IOException
{
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOflines = path.length();
String[] textData = new String[numberOflines];
int count;
for(count = 0; count < numberOflines; count++)
{
textData[count] = textReader.readLine();
}
textReader.close();
return textData;
}
int readLines() throws IOException
{
FileReader fileToRead = new FileReader(path);
BufferedReader br = new BufferedReader(fileToRead);
String aLine;
int numberOfLines = 0;
while ( ( aLine = br.readLine( ) ) != null )
{
numberOfLines++;
}
br.close();
return numberOfLines;
}
}

You could try and iterate in nested for loops like this:
for (int i = 0; i < aryLines.length; i += 10) {
// every iteration brings you to the beginning of a new question
for (int j = 0; j < 6; j++) {
System.out.println(aryLines[i + j]);
}
}

You don't actually even need ReadFile class to read all lines from file. Java provides you Files utility class in java.nio.file package which has readAllLines(Path) method. Also i==6 as mentioned already in comments will let you handle only sixth line, but it will not handle 16th, 26th. To handle these cases you can either create two loops, like in gutenmorgenuhu's answer
for (int questionNumber; ...)
for (1..6 lines of each question)
printLine
or just check if last digit is 6. To get this last digit you can use modulo (reminder) operator % so you condition can be rewritten as if ( i % 10 == 6).
So little simplified code which will handle problem from your question can look like
List<String> lines = Files.readAllLines(Paths.get("input.txt"));
// or in Java 7
// List<String> lines = Files.readAllLines(Paths.get("input.txt"),StandardCharsets.UTF_8);
for (int i = 0; i < lines.size(); i++) {
System.out.println(lines.get(i));
if (i % 10 == 6)
i = i + 3;// or +4 if you don't want to separate questions with empty line
}

Related

Why is my FileReader/BufferReader returning both the sentence and null?

The main thing I am trying to do is input a .txt file into a 2d char array. The problem is that no data is being saved into the array, so I'm thinking my problem lies with the fact that there is no in-between string from the .txt file to the array. I tried using file and buffered readers so I would have a string, and it works, but it adds null many many times. Can someone point out what I am doing wrong here? (I am very new to java, sorry for any errors in question format and such)
See code below, where I'm encountering the problem.
Scanner scanner = new Scanner(new File("Code.txt"));
try {
//had a problem trying to just get the chars out from a file just as a string
// so to a filereader we go!
FileReader Enigma = new FileReader("Code.txt");
// when looking at filereaders, i found bufferedreaders
// they seem to help with reading chars better than the filereader alone
BufferedReader CryptoMachine = new BufferedReader(Enigma);
for (i = 0; i <= rows-1; i++)
{
for (j = 0; j <= columns-1; j++)
{
sentence = CryptoMachine.readLine();
System.out.print(sentence);
}
}
CryptoMachine.close();
}
catch (FileNotFoundException e) {
System.out.println("No file found");
}
Return I get:
This is ridiculously hardnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
Whole code:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
// TODO block code
public class Enigma {
// TODO block code
public static void main(String[] args) throws IOException {
// double array set up here
String sentence = "";
int rows = 6;
int columns = 7;
char[][] RotaryMachine = new char[rows][columns];
boolean flag = false;
// told this lets me declare variables on the same line
int i = 0,j = 0;
// scanner to scan a file here
Scanner scanner = new Scanner(new File("Code.txt"));
try {
//had a problem trying to just get the chars out from a file just as a string
// so to a filereader we go!
FileReader Enigma = new FileReader("Code.txt");
// when looking at filereaders, i found bufferedreaders
// they seem to help with reading chars better than the filereader alone
BufferedReader CryptoMachine = new BufferedReader(Enigma);
for (i = 0; i <= rows-1; i++)
{
for (j = 0; j <= columns-1; j++)
{
sentence = CryptoMachine.readLine();
System.out.print(sentence);
}
}
CryptoMachine.close();
}
catch (FileNotFoundException e) {
System.out.println("No file found");
}
for(i = 0; j > columns && !flag;++i)
{
if(i < rows && !scanner.hasNext())
{
System.out.println("The English have our codes");
flag = true;
}
RotaryMachine[i][j] = scanner.next().charAt(0);
if(i > 6)
{
j++;
}
RotaryMachine[i][j] = '*';
}
// RotaryMachine[0][0] = 'a';
//now, to hopefully code the scrambler section properly, for Enigma to work!
// V2 seems to keep letters really close together
for(i=0;i < columns;++i)
{
for(j = 0;j < rows;++j)
{
System.out.printf("%c", RotaryMachine[j][i]);
}
}
// V1 of the code seems to space out the letters
// for(j=0;j < rows;++j)
// {
// for(i = 0;i < columns;++i)
// {
// System.out.printf("%c", RotaryMachine[j][i]);
// }
// }
}
}
Since the file being read only has one line, readLine will return null for every call past the first since there are no more lines to read.
You can String.split the initial string after reading it if you so desire.

How do I read and save a file into a 2D Array?

I want to read and save the content of the file in a 2d array, but I don't know the size of the file, because the program should read different files. So there is the first problem after "new char". I searched for the problem and found that "matrix[x][y]=zeile.charAt(x);"
should be right, but that throws the error "NullPointerException" when I write any number into the first brackets of new char.
Could somebody explain and give some ideas oder solutions? Thank you :)
import java.io.*;
class Unbenannt
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("Level4.txt");
BufferedReader br = new BufferedReader(fr);
String zeile = br.readLine();
char [][] matrix = new char [][];
while(zeile != null )
{
int y = 0;
for(int x = 0; x < zeile.length(); x++) {
matrix[x][y] = zeile.charAt(x);
}
y++;
} System.out.print(matrix);
br.close();
}
}
Arrays are stored as blocks in memory in order to achieve O(1) operations, which is why you need to define their size during definition. If you insist on arrays (rather than a dynamic ADT such as List), you'll need to know the dimensions in advance.
What you could do is store the file lines temporarily in a list and find out the maximum line length, i.e.:
List<String> lines = new ArrayList<String>();
String zeile = null;
int max = 0;
while ((zeile = br.readLine()) != null) {
lines.add(zeile);
if (zeile.length() > max)
max = zeile.length();
}
char[][] matrix = new char[lines.length()][max];
// populate the matrix:
for (int i = 0; i < lines.length(); i++) {
String line = lines.get(i);
for (int j = 0; j < line.length(); j++) {
matrix[i][j] = line.charAt(j);
}
}
Note that since char is a primitive, you'll be initialized with the default value 0 (the integer, not the character!) in every cell of the inner array, so for lines which are shorter than the others, you'll have trailing zero characters.
you initialize the matrix (char [][]) but you never initialize any of the inbound arrays. This leads to the NullPointerException.
In addition your 'while' condition looks invalid, seems you only are reading the first line of your file here > your code will never complete and read the first line over and over again
Thank you all! It works! But there is still one problem. I changed lines.length() into lines.size(), because it doesn't work with length. The problem is the output. It shows for example: xxxx xxxx instead of "xxx" and "x x" and "xxx" among each other.
How can I build in a line break?
my programcode is:
import java.io.*;
import java.util.ArrayList;
class Unbenannt
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("Level4.txt");
BufferedReader br = new BufferedReader(fr);
ArrayList<String> lines = new ArrayList<String>();
String zeile = null;
int max = 0;
while ((zeile = br.readLine()) != null) {
lines.add(zeile);
if (zeile.length() > max)
max = zeile.length();
}
char [][] matrix = new char[lines.size()][max];
for(int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
for(int j = 0; j < line.length(); j++) {
matrix[i][j] = line.charAt(j);
System.out.print(matrix[i][j]);
}
}
br.close();
}
}

Saturday Night Java Fun with 2D arrays, and reading a text based tab delimited file to populate such an array

Hey guys and gals hope everyones Saturday night is going as swimmingly (preferably more) than mine own.
I'm a java noob so bear with me.
We are told to export the an excel sheet from Open Office into a .txt (Tab Delimited)
It ends up looking like this
1 2 3
4 5 6
7 8 9
10 11 12
Where all values are separated by a tab.. (something I haven't encountered yet and are Integer values)
I can see one option, as i type this as I could capture each line, then string split the line by?? whitespace or /t ... and then assign the values to the respective positions in the [30][10] array...
(which ends up being a .csv and load it into java.
So Job 1 is to populate a 2D array with the files from the tab delimited file.
import java.util.Scanner;
import java.io.File;
import java.util.Arrays;
public class Nitrogen
{
private int elevations[][] = null;
private String filename = "location.txt";
public Nitrogen()
{
int [][]elevations = new int[30][10];
}
public void run()
{
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int[][] elevations = new int[30][10];
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < columns; ++j)
{
if(input.hasNextInt())
{
elevations[i][j] = input.nextInt();
}
}
for (int h=0; h < rows; h++) {
for (int g=0; g < columns; g++)
System.out.print(elevations[h][g] +" ");
}
System.out.println("");
}
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);}
}
public static void main(String[] args)
{
Nitrogen n = new Nitrogen();
n.run();
}
}
So, this prints out 30 lines of line 1, then a line of 0's on top of 29 lines of line 2, then 2 lines of 0's on top of 28 lines of line 3, You get the point....all moving left to right.
Not quite sure....tis getting late and i might give up for the evening.
Alright!! Here is the solution... persistence pays of thanks for the help everyone
public void populate()
{
try{
File file = new File(filename);
Scanner input = new Scanner(file);
int rows = 30;
int columns = 10;
int[][] elevations = new int[30][10];
for(int i = 0; i < rows; ++i){
for(int j = 0; j < columns; ++j)
{
if(input.hasNextInt())
{
elevations[i][j] = input.nextInt();
}
}
}
for (int h=0; h < rows; h++){ //This was just to show I had it
for (int g=0; g < columns; g++) { //in there correctly
System.out.print(elevations[h][g] +" ");
}
System.out.println(""); }
}
catch (java.io.FileNotFoundException e) {
System.out.println("Error opening "+filename+", ending program");
System.exit(1);}
}
If you are trying to print out the array, I would suggest the following amendment to your code:
for (int h=0; h < rows; h++) {
for (int g=0; g < columns; g++)
System.out.print(elevations[h][g] + " ");
}
System.out.println("");
}
The above will produce an output such as:
Row1, Row1, Row1
Row2, Row2, Row2
Because it prints out the columns, with a space in between each element, then a new line between the rows.
I know this is a simple assignment for a class, but if you can use Collections for IO, please do so. It makes the code much more generally usable.
If you want to read values from a tab delimited file (in OpenOffice, this is called a {Tab} delimited CSV file in the Save dialog window), the easiest you can do, is split each line according to a tab, like this:
public static ArrayList<ArrayList<Integer>> readFile(String filename) throws IOException {
File file = new File(filename);
BufferedReader br = new BufferedReader(new FileReader(file));
ArrayList<ArrayList<Integer>> list = new ArrayList<>(); // list of lines
String buffer;
while ((buffer = br.readLine()) != null) {
String[] splitted = buffer.split("\t"); // split the lines by tabs
ArrayList<Integer> line = new ArrayList<>();
for (String str : splitted) {
line.add(Integer.parseInt(str)); // cast and add all the integers to a list
}
list.add(line); // add the line to the list of lines
}
return list;
}
We are able to create a list of lines, with each line containing the Integer values from the text file. Now, we need to create a 2D list out of it, so concatenate all the values from every line to the line before.
public static ArrayList<Integer> concatenateAll(ArrayList<ArrayList<Integer>> lines) {
ArrayList<Integer> result = new ArrayList<>(); // create an empty 2D list for all the values
for(ArrayList<Integer> line : lines) {
result.addAll(line); // add all the values from every line to the 2D list
}
return result;
}
We can create a 2D list of all the values in the file. To use these two methods, we need to invoke them like this:
public static void main(String[] args) {
ArrayList<ArrayList<Integer>> lineList = null;
try {
lineList = readFile("table.csv");
} catch (IOException ioe) {
ioe.printStackTrace();
}
ArrayList<Integer> allLines = concatenateAll(lineList);
System.out.println(allLines);
}
If we absolutely need an array, we can add this at the end:
Integer[] linesArray = new Integer[allLines.size()];
allLines.toArray(linesArray);
System.out.println(Arrays.toString(linesArray));
For non-class assignments, here's a one liner:
private string[][] Deserialize(string data)
{
return ( from string line
in data.Split('\r\n')
select line.Split(' ')
).ToArray();
}

how to separate values in a string index that are char and int

okay basically im wanting to separate the elements in a string from int and char values while remaining in the array, but to be honest that last parts not a requirement, if i need to separate the values into two different arrays then so be it, id just like to keep them together for neatness. this is my input:
5,4,A
6,3,A
8,7,B
7,6,B
5,2,A
9,7,B
now the code i have so far does generally what i want it to do, but not completely
here is the output i have managed to produce with my code but here is where im stuck
54A
63A
87B
76B
52A
97B
here is where the fun part is, i need to take the numbers and the character values and separate them so i can use them in a comparison/math formula.
basically i need this
int 5, 4;
char 'A';
but of course stored in the array that they are in.
Here is the code i have come up with so far.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
public class dataminingp1
{
String[] data = new String[100];
String line;
public void readf() throws IOException
{
FileReader fr = new FileReader("C:\\input.txt");
BufferedReader br = new BufferedReader(fr);
int i = 0;
while ((line = br.readLine()) != null)
{
data[i] = line;
System.out.println(data[i]);
i++;
}
br.close();
System.out.println("Data length: "+data.length);
String[][] root;
List<String> lines = Files.readAllLines(Paths.get("input.txt"), StandardCharsets.UTF_8);
root = new String[lines.size()][];
lines.removeAll(Arrays.asList("", null)); // <- remove empty lines
for(int a =0; a<lines.size(); a++)
{
root[a] = lines.get(a).split(" ");
}
String changedlines;
for(int c = 0; c < lines.size(); c++)
{
changedlines = lines.get(c).replace(',', ' '); // remove all commas
lines.set(c, changedlines);// Set the 0th index in the lines with the changedLine
changedlines = lines.get(c).replaceAll(" ", ""); // remove all white/null spaces
lines.set(c, changedlines);
changedlines = lines.get(c).trim(); // remove all null spaces before and after the strings
lines.set(c, changedlines);
System.out.println(lines.get(c));
}
}
public static void main(String[] args) throws IOException
{
dataminingp1 sarray = new dataminingp1();
sarray.readf();
}
}
i would like to do this as easily as possible because im not to incredibly far along with java but i am learning so if need be i can manage with a difficult process. Thank you in advance for any at all help you may give. Really starting to love java as a language thanks to its simplicity.
This is an addition to my question to clear up any confusion.
what i want to do is take the values stored in the string array that i have in the code/ input.txt and parse those into different data types, like char for character and int for integer. but im not sure how to do that currently so what im asking is, is there a way to parse these values all at the same time with out having to split them into different arrays cause im not sure how id do that since it would be crazy to go through the input file and find exactly where every char starts and every int starts, i hope this cleared things up a bit.
Here is something you could do:
int i = 0;
for (i=0; i<list.get(0).size(); i++) {
try {
Integer.parseInt(list.get(0).substring(i, i+1));
// This is a number
numbers.add(list.get(0).substring(i, i+1));
} catch (NumberFormatException e) {
// This is not a number
letters.add(list.get(0).substring(i, i+1));
}
}
When the character is not a number, it will throw a NumberFormatException, so, you know it is a letter.
for(int c = 0; c < lines.size(); c++){
String[] chars = lines.get(c).split(",");
String changedLines = "int "+ chars[0] + ", " + chars[1] + ";\nchar '" + chars[0] + "';";
lines.set(c, changedlines);
System.out.println(lines.get(c));
}
It is very easy, if your input format is standartized like this. As long as you dont specify more (like can have more than 3 variables in one row, or char can be in any column, not only just third, the easiest approach is this :
String line = "5,4,A";
String[] array = line.split(",");
int a = Integer.valueOf(array[0]);
int b = Integer.valueOf(array[1]);
char c = array[2].charAt(0);
Maybe something like this will help?
List<Integer> getIntsFromArray(String[] tokens) {
List<Integer> ints = new ArrayList<Integer>();
for (String token : tokens) {
try {
ints.add(Integer.parseInt(token));
} catch (NumberFormatException nfe) {
// ...
}
}
return ints;
}
This will only grab the integers, but maybe you could hack it around a bit to do what you want :p
List<String> lines = Files.readAllLines(Paths.get("input.txt"), StandardCharsets.UTF_8);
String[][] root = new String[lines.size()][];
for (int a = 0; a < lines.size(); a++) {
root[a] = lines.get(a).split(","); // Just changed the split condition to split on comma
}
Your root array now has all the data in the 2d array format where each row represents the each record/line from the input and each column has the data required(look below).
5 4 A
6 3 A
8 7 B
7 6 B
5 2 A
9 7 B
You can now traverse the array where you know that first 2 columns of each row are the numbers you need and the last column is the character.
Try this way by using getNumericValue() and isDigit methods. This might also work,
String myStr = "54A";
boolean checkVal;
List<Integer> myInt = new ArrayList<Integer>();
List<Character> myChar = new ArrayList<Character>();
for (int i = 0; i < myStr.length(); i++) {
char c = myStr.charAt(i);
checkVal = Character.isDigit(c);
if(checkVal == true){
myInt.add(Character.getNumericValue(c));
}else{
myChar.add(c);
}
}
System.out.println(myInt);
System.out.println(myChar);
Also check, checking character properties

A Good Method to read files in Java

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.

Categories