I've worked with Java for a few years but during that time I've almost never had to do anything with text files. I need to know how to read lines of a text file into different variables as two-digit integers, along with several lines of said text file into a 2D integer array. Every text file is to be written like this:
5 5
1 2
4 3
2 4 2 1 4
0 1 2 3 5
2 0 4 4 1
2 5 5 3 2
4 3 3 2 1
The first three lines should all be separate integers, but the first line is indicative of the 2D array's dimensions. The last segment needs to go into that integer array. This is what I've got so far in terms of code.
import java.util.*;
import java.io.*;
public class Asst1Main {
public static void main(String[]args){
try {
x = new Scanner(new File("small.txt"));
} catch (FileNotFoundException e) {
System.out.println("File not found.");
}
while(x.hasNext()){
}
}
}
I'm completely at a loss of how to do this.
Here is some psuedoish code
Scanner input = new Scanner(new File("blammo.txt"));
List<String> data = new ArrayList<String>();
String line1;
String line2;
String line3;
line1 = readALine(input);
line2 = readALine(input);
line3 = readALine(input);
... process the lines as you see fit. perhaps String.split(line1);
while (input.hasNextLine())
{
String current = input.nextLine();
data.add(current);
}
private String readALine(final Scanner input)
{
String returnValue;
if (input.hasNextLine())
{
returnValue = input.nextLine();
}
else
{
returnValue = null; // maybe throw an exception instead.
}
return returnValue;
}
Once you have the data (or perhaps while reading it), you can split it and process it as you see fit.
Start with an ArrayList of integer arrays instead. It'll be easier to do this:
ArrayList<Integer[]> list = new ArrayList<Integer>();
String line = scanner.nextLine();
String[] parts = line.split("[\\s]");
Integer[] pArray = new Integer[parts.length];
for (Integer x = 0; x < parts.length; x++) {
pArray[x] = Integer.parseInt(parts[x]);
}
list.add(pArray);
Do the bulk of that inside of a loop obviously.
Here is a full version.
import java.util.*;
import java.io.*;
public class Asst1Main {
public static void main(String[] args) {
Scanner in;
try {
in = new Scanner(new File("small.txt"));
} catch (FileNotFoundException e) {
System.out.println("File not found.");
return;
}
int rows = in.nextInt();
int cols = in.nextInt();
int startRow = in.nextInt();
int startCol = in.nextInt();
int endRow = in.nextInt();
int endCol = in.nextInt();
int[][] map = new int[rows][cols];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
map[row][col] = in.nextInt();
}
}
}
}
Related
I am reading multiple lines from the command line looking like this:
10 12
71293781758123 72784
1 12345677654321
Then I calculate stuff with the data of each line and output exactly the same amount of lines.
Unfortunately, I never get more than one line output in the end, namely the result of the last one.
The input function looks like that:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
String line = input.nextLine();
String[] lines = line.split(" ");
System.out.println(fct(lines[0], lines[1]));
}
input.close();
}
fct outputs a String.
Is there something weird happening I am not aware of?
Edit: I have added fct,since this could also be the problem:
public static String fct(String stringA, String stringB) {
int [] a = new int[stringA.length()];
int [] b = new int[stringB.length()];
for(int i=0; i< stringA.length(); i++) {
a[i] = stringA.charAt(i) - '0';
}
for(int i=0; i< stringB.length(); i++) {
b[i] = stringB.charAt(i) - '0';
}
if(a.length < b.length) {
int[] c = a.clone();
a = b.clone();
b = c.clone();
}
Stack<Integer> s = new Stack<Integer>();
int carry = 0;
int b_ind = b.length -1;
for(int i=a.length-1; i>=0; i--) {
if(b_ind >= 0) {
int diff = a[i] - b[b_ind] - carry;
if(diff < 0) {
carry = 1;
diff = 10 + diff;
} else {
carry = 0;
}
s.push(diff);
} else {
if(carry==0) {
s.push(a[i]);
} else {
s.push(a[i]-carry);
carry = 0;
}
}
b_ind -= 1;
}
String all = "";
while(!s.empty()) {
all = all + s.pop();
}
return all.replaceFirst("^0+(?!$)", "").trim();
}
The output would then be:
2
71293781685339
12345677654320
Being directly on the console on the line after the input finished.
Add one line break after last input line 1 12345677654321. Otherwise program won't read last line till you press enter(return) key.
If you want output on console like this:
10 12
71293781758123 72784
1 12345677654321
98
71293781685339
12345677654320
But you are getting this:
10 12
71293781758123 72784
1 1234567765432198
71293781685339
Notice, 98 is getting appended to last input line. And the second output is on the next line. You actually have two outputs.
And the third input has not been read by the program because third input line doesn't end in new line. If you press Enter key here the program will process the third input.
You need to make sure that there is a new line character after last input line before pasting entire input in to console.
Just a sidenote:
I would use java.math.BigInteger in this context (math with big integers).
import java.util.Scanner;
import java.math.BigInteger;
public class Main {
public static void main(String[] args) {
try (var scanner = new Scanner(System.in)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] lines = line.split(" ");
System.out.println(fct(lines[0], lines[1]));
}
}
}
public static String fct(String numberA, String numberB) {
var a = new BigInteger(numberA);
var b = new BigInteger(numberB);
return a.subtract(b).abs().toString();
}
}
I'm trying to read a large text file of about 7516 lines of text. When I read a smaller file (9 lines) the program works fine. But with the large file it seems to get caught in something and just keeps running without anything actually happening.I'm not sure where to start looking for the issue.
The code reads a text file and then turn it into an array. Then it passes the array into a shuffle and writes it into another text file. Or at least that's what I want it to do.
package Rn1;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class Read2 {
static void randomShuffle( int arr[], int n)
{
// Creating a object for Random class
Random r = new Random();
// Start from the last element and swap one by one. We don't
// need to run for the first element that's why i > 0
for (int i = n-1; i > 0; i--) {
// Pick a random index from 0 to i
int j = r.nextInt(i+1);
// Swap arr[i] with the element at random index
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// Prints the random array
System.out.println(Arrays.toString(arr));
}
public static String readString(String file) {
String text = "";
try {
Scanner s = new Scanner(new File(file));
while(s.hasNext()) {
text = text + s.next() + " ";
}
}
catch(FileNotFoundException e) {
System.out.println("Not Found");
}
return text;
}
public static String[] readArray(String file) {
//Step 1:
//Count how many elements in the file (lines)
//Step 2
//Create array
int ctr = 0;
try {
Scanner s1 = new Scanner(new File(file));
while (s1.hasNextLine()) {
ctr = ctr +1;
if (s1.hasNext()) {
s1.next();
}
}
String[] words = new String[ctr];
Scanner s2 = new Scanner(new File(file));
for(int i = 0; i < ctr; i = i+1){
words[i] = s2.next();
}
return words;
}
catch (FileNotFoundException e) {
}
return null;
}
public static void main(String[] args) throws Exception
{
//String text = readString("C:\\Users\\herna\\Desktop\\Test.txt");
//System.out.println(text);
String[] words = readArray("C:\\Users\\herna\\Desktop\\ErdosCA.txt");
int n = words.length;
int [] arr = new int [n];
PrintWriter writer = new PrintWriter("the-file-name.txt", "UTF-8");
for (int i=0; i < words.length; i = i + 1 )
{
arr[i] = Integer.parseInt(words[i]);
//writer.println(words[i]);
}
//System.out.println(Arrays.toString(arr));
randomShuffle(arr, n);
writer.println(Arrays.toString(arr));
//writer.println(Arrays.toString(words));
//writer.println("Update*");
writer.close();
}
}
The program is also reproducable with small files, for example:
1
2
3
The program enters an endless loop when the last line of the file is empty. The bad part is this:
Scanner s1 = new Scanner(new File(file));
while (s1.hasNextLine())
{
ctr = ctr + 1;
if (s1.hasNext())
{
s1.next();
}
}
If you are before the empty line, then s1.hasNextLine() is true but s1.hasNext() is false. So you do not read the next element. Then in the next iteration of the loop, s1.hasNextLine() is still true, and thus the loop does never end.
By the way, you should never catch Exceptions without handling them. You should at least output an error message and then call e.printStackTrace().
My knowledge with java language is very new. Most of my knowledge are from googling up on how to do things. I've been working on a console program in java that uses a switch statement. The entire program utilizes an String [20][5] array. I've written the code to now be able to add entry, save array to file, load entries from file into the array.
The problems now is edit and removing entries. I am able to return values to null but it'll look like this [[null], [null, null, null, null, null].
I want the value to return to [null, null, null, null, null], [null, null, null, null, null].
The Edit entry some reasons return an java.lang.ArrayIndexOutOfBoundsException:1 .
Could someone point out my error? Also the Array is globally declare.
public static String[][] rem(){
Scanner input = new Scanner(System.in);
int x,y=0;
//for(int i=0;i<array.length;i++){
//if(array[i][0]!=null){
System.out.println(Arrays.deepToString(array));//}
//}
System.out.println("Which entry would you like to remove? "
+ "\n" + "Enter number 0 - 20");
x = input.nextInt();
array[x][y]=null;
return array;}
public static String[][] edit(){
Scanner input = new Scanner(System.in);
String k;
int j;
int g;
// for(int i=0;i<array.length;i++){
//if(array[i][0]!=null){
//System.out.println(Arrays.deepToString(array));}
//}
System.out.println("Which entry would you like to edit? "
+ "\n" + "Enter number 0 - 20");
j = input.nextInt();
System.out.println("What would you like to edit? "
+"\n" + "Enter number 0 - 5");
g = input.nextInt();
System.out.println("You are now editing.");
k = input.next();
array[j][g] = k;
return array;}
Update
I think I figure my issue. The array properly edit values I manually input. It's when I load data into the array that causes problem because when it loads data it loads as String []. I need a code that will load the data as String[][] or as array of arrays.
public static String[][] load()throws FileNotFoundException, IOException{
menu();
copyFile();
String file = ("c:/temp/Address.txt");
Scanner scan = new Scanner(new FileReader(file));
// initialises the scanner to read the file file
//String[][] entries = new String[100][3];
// creates a 2d array with 100 rows and 3 columns.
//int i = 0;
while(scan.hasNextLine()){
array[i][i] = scan.next().split("," , "\t");
i++;
}
//loops through the file and splits on a tab
//for (int row = 0; row < array.length; row++) {
// for (int col = 0; col < array[0].length; col++) {
// if(array[row][col] != null){
// System.out.print(array[row][0] );
// }
// }
// if(array[row][0] != null){
// System.out.print("\n");
//}
// }
//prints the contents of the array that are not "null"
selectMenu();
return array;}
Update 2
I have found the solution to solving the loading data issue. The solution is simple! I'll leave the code here for reference. Though, all of the codes could use some beautifying.
public static String[][] load()throws FileNotFoundException, IOException{
menu();
copyFile();
String file = ("c:/temp/Address.txt");
Scanner scan = new Scanner(new FileReader(file));
FileReader fr = new FileReader("c:/temp/Address.txt");
BufferedReader br = new BufferedReader(fr);
//int j=0;
//int lineNo = 0;
//String line = br.readLine();
//while(line!=null)
//{
//for(int i = 0; i < 5; i++)
//{
//array[lineNo][i] = line.substring(i,4);
//}
// lineNo++;
//line = br.readLine(); // This is what was missing!
//}
//while(scan.hasNextLine()){
//while(scan.hasNext()){
//for(j=0;j<5;j++){
for(int i = 0; i < 20; ++i){
for(int j = 0; j < 5; ++j)
{
if(scan.hasNext())
{
array[i][j] = scan.next();
//i++;
//j++;
}
//i++;
}
}
selectMenu();
return array;}
Update 3
So after figuring out on how to use the delimiter it sorts of give me a weird issue. It adds return at the end of the column. [null, null, null, null, null return]. I used ",|\n" as my delimiter. Is there a better method? Update: Added a .trim(); solve the final issue with load. Now it's perfected in its current job. Though, I'm sure there might be less primitive methods.
public static String[][] load()throws FileNotFoundException, IOException{
copyFile();
//delimiter removes the comma or return to the next line. "\n" new line
Scanner scan = new Scanner(new FileReader(file)).useDelimiter(",|\n");
for(int i = 0; i < 20; ++i){
for(int j = 0; j < 5; ++j){
if(scan.hasNext())
array[i][j] = scan.next().replace(",", "").trim();
}
}
System.out.println("File loaded successfully!!");
scan.close();
return array;}
This is an off by one error, very subtle mistake:
Although you have 20 rows and 5 columns, arrays use a 0 based index(start counting from 0 instead of 1).
Use your fingers to count from 0 - 5 and you will see that there are actually 6 numbers instead of 5 which is causing your OutOfBoundsException as you don't have a 6th element.
Therefore to access your rows and columns, the range should be between:
0 - 19 (for the columns) and 0 - 4 (for the rows)
Or
1 - 20 (for the columns) and 1 - 5 (for the rows) and then subtract 1 from your scanners input since remember arrays use 0 based index.
update for the file reading:
public static String[][] load() {
try{
FileReader fr = new FileReader("c:/temp/Address.txt");
BufferedReader bf = new BufferedReader(fr);
String presentLine = "";
for(int i = 0; i < 20; i++) {
for(int j = 0; i < 5; j++) {
if ((presentLine = bf.readLine()) != null) {
array[i][j] = presentLine;
}
}
}
} catch(Exception e) {
System.out.println(e);
}
selectMenu();
return array;
}
Although this could be made way better but it's okay.
You could store 20 and 5 as static variables called rows and columns respectively to avoid using hard coded numbers.
So basically i am trying to read a .txt file that contains these following in it:
3 5
2 3 4 5 10
4 5 2 3 7
-3 -1 0 1 5
and store them into 2D array and print it on console, what i got from the console is fine but only missing the first row 3 5, which i do not know what is wrong with my code made it ignored the first line.
what i got as output now:
2 3 4 5 10
4 5 2 3 7
-3 -1 0 1 5
import java.io.*;
import java.util.*;
public class Driver0 {
public static int[][] array;
public static int dimension1, dimension2;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Welcome to Project 0.");
System.out.println("What is the name of the data file? ");
String file = input.nextLine();
readFile(file);
}
public static void readFile(String file) {
try {
Scanner sc = new Scanner(new File(file));
dimension1 = sc.nextInt();
dimension2 = sc.nextInt();
array = new int[dimension1][dimension2];
while (sc.hasNext()) {
for (int row = 0; row < dimension1; row++) {
for (int column = 0; column < dimension2; column++) {
array[row][column] = sc.nextInt();
System.out.printf("%2d ", array[row][column]);
}
System.out.println();
}
}
sc.close();
}
catch (Exception e) {
System.out
.println("Error: file not found or insufficient requirements.");
}
}
}
You're reading those numbers in this part of your code:
dimension1 = sc.nextInt();
dimension2 = sc.nextInt();
So dimension1 gets the value of 3 and dimension2gets the value of 5, but you're not saving them into the array.
Try this code....
import java.io.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
public class Proj4 {
public static int rows, cols;
public static int[][] cells;
/**
* main reads the file and starts
* the graphical display
*/
public static void main(String[] args) throws IOException {
Scanner s = new Scanner(System.in);
String file = JOptionPane.showInputDialog(null, "Enter the input file name: ");
Scanner inFile = new Scanner(new File(file));
rows = Integer.parseInt(inFile.nextLine());
cols = Integer.parseInt(inFile.nextLine());
cells = new int[rows][cols];
//this is were I need help
for(int i=0; i < rows; i++)
{
String line = inFile.nextLine();
line = line.substring(0);
}
inFile.close();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
System.out.print(cells[i][j]);
}
System.out.print();
}
You can use Stream API to do it easily
public static Integer[][] readFile(String path) throws IOException {
return Files.lines(Paths.get(path)) // 1
.filter(line -> !line.trim().isEmpty()) // 2
.map(line -> Arrays.stream(line.split("[\\s]+")) // 3
.map(Integer::parseInt) // 4
.toArray(Integer[]::new)) // 5
.toArray(Integer[][]::new); // 6
}
Read the file as Stream of Lines
Ignore empty lines
Split each line by spaces
Parse splitted String values to get Integer values
Create an array of Integer values
Collect it in 2D-Array
The first two values are being saved into dimension1 and dimension2 variables, so when sc.nextInt gets called later, it's already read the first two numbers and moves on to the next line. So those first ints don't make it into the array.
A few things to consider:
You're wanting to use the entire file, so I would read the whole thing in at once with Files.readAllLines(). This function returns a List<String> which will have all the lines to your file. If there are any blank lines, remove them and now you have the number of rows to declare for your 2d array.
Each line is space delimited, so a simple String.split() on each line in your List<String> will give you the number of columns each row should have.
Splitting each line and converting them to integers can be done with a nested for loops which is normal for processing 2d arrays.
For Example:
public static void main(String[] args) throws Exception {
// Read the entire file in
List<String> myFileLines = Files.readAllLines(Paths.get("MyFile.txt"));
// Remove any blank lines
for (int i = myFileLines.size() - 1; i >= 0; i--) {
if (myFileLines.get(i).isEmpty()) {
myFileLines.remove(i);
}
}
// Declare you 2d array with the amount of lines that were read from the file
int[][] intArray = new int[myFileLines.size()][];
// Iterate through each row to determine the number of columns
for (int i = 0; i < myFileLines.size(); i++) {
// Split the line by spaces
String[] splitLine = myFileLines.get(i).split("\\s");
// Declare the number of columns in the row from the split
intArray[i] = new int[splitLine.length];
for (int j = 0; j < splitLine.length; j++) {
// Convert each String element to an integer
intArray[i][j] = Integer.parseInt(splitLine[j]);
}
}
// Print the integer array
for (int[] row : intArray) {
for (int col : row) {
System.out.printf("%5d ", col);
}
System.out.println();
}
}
Results:
3 5
2 3 4 5 10
4 5 2 3 7
-3 -1 0 1 5
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();
}