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();
}
}
Related
The input my program gets are a few strings of characters which represents rows in a matrix. I would like to put the columns of this matrix in a LinkedHashMap, but without first storing everything in an array and then construct the columns and put them in the LinkedHashMap. The idea is that this should be done as fast as possible.
Example:
Input:
abfad
grgaa
rtwag
The strings that should be saved in a LinkedHashMap are:
agr
brt
fgw
aaa
dag
Edit:
This is how my program does it right now:
String[][] array = new String[n][m];
LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
for (int i = 0; i < n; i++) {
array[i] = br.readLine().split("");
}
for (int i = 0; i < m; i++) {
String column = "";
for (int j = 0; j < n; j++) {
column += array[j][i];
}
map.put(i, column);
}
I am not sure why this is downvoted.
It's an interesting problem that you should perhaps ask a little better.
Does it help if you think of this as a real-time transform of a matrix? What should happen when you read the first line? What should happen for each subsequent line? We are assuming that all lines have same length, otherwise we'll need to specify what happens when they are not.
After you have tried on your own, maybe you can take a look below. I have not used LinkedHashMap there, also I have used the mutable StringBuilder. But you can easily modify it to use the data structure of your choice.
public class RealTimeTransform {
public static void main(String[] args) throws IOException {
Map<Integer, StringBuilder> columns = new HashMap<>();
readColumnsFromRows(columns, System.in);
System.out.println(columns.values());
}
private static void readColumnsFromRows(Map<Integer, StringBuilder> columns, InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
int rc = 0;
String row;
while ((row = reader.readLine()) != null) {
if (rc == 0) {
for (int i = 0; i < row.length(); i++) {
columns.put(i, new StringBuilder(10).append(row.charAt(i)));
}
} else {
for (int i = 0; i < row.length(); i++) {
columns.get(i).append(row.charAt(i));
}
}
rc += 1;
}
}
}
This prints:
aman
plan
yess
[apy, mle, aas, nns]
per your specification.
I try to convert a file to an array of integers, do not know where my mistake is that when I print the array empty array throws
I leave my method , thanks you
public int[] ConvertToArray(File xd) throws IOException {
String sCadena;int i=0;
int[]array;
FileReader fr = new FileReader(xd);
BufferedReader bf = new BufferedReader(fr);
int lNumeroLineas = 0;
while ((sCadena = bf.readLine())!=null) {
lNumeroLineas++;
}
array = new int[lNumeroLineas];
while ((sCadena = bf.readLine())!=null) {
lNumeroLineas++;
array[i]=Integer.parseInt(sCadena);
i++;
}
for (int j = 0; j < array.length; j++) {
System.out.println(array[i]);
}
return array;
}
You are already at the end of file after your first while loop completes.
So reading from BufferedReader object bf again after first while loop ends will always give you null(End of file) and second iteration will never run.
Also in the for loop you are printing array[i] however for loop is iterating over j variable
You can do it like this with help of ArrayList:
public int[] ConvertToArray(File xd) throws IOException {
String sCadena;
ArrayList<Integer> array = new ArrayList();
FileReader fr = new FileReader(xd);
BufferedReader bf = new BufferedReader(fr);
int lNumeroLineas = 0;
while ((sCadena = bf.readLine())!=null) {
lNumeroLineas++;
array.add(Integer.parseInt(sCadena.trim())); //always recomended to trim(); to remove trailing whitespaces.
}
for (int j = 0; j < array.size(); j++) {
System.out.println(array.get(j));
}
return covertIntegers(array);
}
Edited: If you want to send int[] instead of ArrayList<Integer> without using any external libraries.
public static int[] convertIntegers(List<Integer> integers)
{
int[] ret = new int[integers.size()];
for (int i=0; i < ret.length; i++)
{
ret[i] = integers.get(i).intValue();
}
return ret;
}
You are reading the file with two loops but open only once. Reopen the file reader before the second while and it will work.
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
}
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();
}
what makes it only be able to input 10*10 text files
package game;
import java.io.*;
import java.util.*;
public class Level {
static public void main(String[] args) throws IOException {
File f = new File("Data1.txt");
int[][] m = Map(f);
for (int x = 0; x < m.length; x++) {
for (int y = 0; y < m[x].length; y++) {
System.out.print(m[x][y]);
}
System.out.println();
}
}
public static int[][] Map(File f) throws IOException {
ArrayList line = new ArrayList();
BufferedReader br = new BufferedReader(new FileReader(f));
String s = null;
while ((s = br.readLine()) != null) {
line.add(s);
}
int[][] map = new int[line.size()][];
for (int i = 0; i < map.length; i++) {
s = (String) line.get(i);
StringTokenizer st = new StringTokenizer(s, " ");
int[] arr = new int[st.countTokens()];
for (int j = 0; j < arr.length; j++) {
arr[j] = Integer.parseInt(st.nextToken());
}
map[i] = arr;
}
return map;
}
}
if i put in a text file that is
10*10 or less characters it works
otherwise it comes out with a numberformatexception
fixed
package game;
import java.io.*;
import java.util.*;
public class Level {
static public void main(String[] args) throws IOException {
File f = new File("Data1.txt");
int[][] m = Map(f);
for (int x = 0; x < m.length; x++) {
for (int y = 0; y < m[x].length; y++) {
System.out.print(m[x][y]);
}
System.out.println();
}
}
public static int[][] Map(File f) throws IOException {
ArrayList line = new ArrayList();
BufferedReader br = new BufferedReader(new FileReader(f));
String s = null;
while ((s = br.readLine()) != null) {
line.add(s);
}
int[][] map = new int[line.size()][];
for (int i = 0; i < map.length; i++) {
s = (String) line.get(i);
char[] m = s.toCharArray();
String[] n = new String[m.length];
for (int t = 0; t<m.length;t++)
{
n[t] = ""+m[t];
}
int[] arr = new int[m.length];
for (int j = 0; j < arr.length; j++) {
arr[j] = Integer.parseInt(n[j]);
}
map[i] = arr;
}
return map;
}
}
Contrary to notes in the comments, your program seems to work with large files, and with long lines, as long as there are enough spaces.
I think your issue is actually that whenever the text file has a token with more than 10 characters it throws a NumberFormatException.
That would be because Integer.MAX_INT is 2147483647, which has 10 characters when written as a String, and Integer.parseInt just can't handle more digits than that.
You're splitting on space and expecting everything to parse as an integer, and some of your numbers are too big for Java's integer data type.
Int's max value is: 2,147,483,647 or 2147483647 without the commas. That's 10 characters. attempting to parse an 11 character string to an int would result in a number that is beyond the Int's max value, hence, the NumberFormatException.