Scanning from a certain, random line of a file in java? - java

I have a .txt file that lists integers in groups like so:
20,15,10,1,2
7,8,9,22,23
11,12,13,9,14
and I want to read in one of those groups randomly and store the integers of that group into an array. How would I go about doing this? Every group has one line of five integers seperated by commas. The only way I could think of doing this is by incrementing a variable in a while loop that would give me the number of lines and then somehow read from one of those lines that is chosen randomly, but I'm not sure how it would read from only one of those lines randomly. Here's the code that I could come up with to sort of explain what I'm thinking:
int line = 0;
Scanner filescan = new Scanner (new File("Coords.txt"));
while (filescan.hasNextLine())
{
line++;
}
Random r = new Random(line);
Now what do I do to make it scan line r and place all of the integers read on line r into a 1-d array?

There is an old answer in StackOverflow about choosing a line randomly. By using the choose() method you can randomly get any line. I take no credit of the answer. If you like my answer upvote the original answer.
String[] numberLine = choose(new File("Coords.txt")).split(",");
int[] numbers = new int[5];
for(int i = 0; i < 5; i++)
numbers[i] = Integer.parseInt(numberLine[i]);

I'm assuming you know how to parse the line and get the integers out (Integer.parseInt, perhaps with a regular expression). If you're sing a scanner, you can specify that in your constructor.
Keep the contents of each line, and use that:
int line = 0;
Scanner filescan = new Scanner (new File("Coords.txt"));
List<String> content = new ArrayList<String>(); // new
while (filescan.hasNextLine())
{
content.add(filescan.next()); // new
line++;
}
Random r = new Random(line);
String numbers = content.get(r.nextInt(content.size()); // new
// Get numbers out of "numbers"

Read lines one by one from the file, store them in a list and generate a random number from the list's size and use it to get the random line.
public static void main(String[] args) throws Exception {
List<String> aList = new ArrayList<String>();
Scanner filescan = new Scanner(new File("Coords.txt"));
while (filescan.hasNextLine()) {
String nxtLn = filescan.nextLine();
//there can be empty lines in your file, ignore them
if (!nxtLn.isEmpty()) {
//add lines to the list
aList.add(nxtLn);
}
}
System.out.println();
Random r = new Random();
int randomIndex=r.nextInt(aList.size());
//get the random line
String line=aList.get(randomIndex);
//make 1 d array
//...
}

Related

Extracting String from a specefic line in a txt file [duplicate]

This question already has answers here:
How to read a specific line using the specific line number from a file in Java?
(19 answers)
Closed 3 years ago.
Im a novice java learner, i have a little problem and i hope you guys can help me out.
i have a Names.txt file that contains a huge amount of random names, each line has an appropriate name
(expl:
jhon
Micheal
Anthony
etc...)
I've been writing a function that randomly choses one of these names:
public static void RandomNameGenerator() throws FileNotFoundException
{
// the File.txt has organized names, meaning that each line contains a name
//the idea here is to get a random int take that number and find a name corresponding to that line number
int txtnumlines = 0; // how many lines the txt file has
Random random = new Random();
Scanner file = new Scanner(new File("Names.txt")); //loads the txt file
while (file.hasNext()) //counts the number of lines
{
file.nextLine();
txtnumlines += 1;
}
int randomintname = random.nextInt(txtnumlines);
// takes a random number, that number will be used to get the name from the txt line
String RandomName = "";
// I'm stuck here :(
}
the problem is i don't know how to continue, more specifically how to extract that name (let's say alex) using the random integers i have that represents a random line
hope my question was clear,
Thank you for helping me out!
Here, you might want to try this:
public static void RandomNameGenerator() throws FileNotFoundException
{
// the File.txt has organized names, meaning that each line contains a name
//the idea here is to get a random int take that number and find a name corresponding to that line number
int txtnumlines = 0; // how many lines the txt file has
Random random = new Random();
Scanner file = new Scanner(new File("Names.txt")); //loads the txt file
Scanner fileReloaded = new Scanner(new File("Names.txt")); //Let's use another one since we can't reset the first scanner once the lines have been counted (I'm not sure tho)
while (file.hasNext()) //counts the number of lines
{
file.nextLine();
txtnumlines += 1;
}
int randomintname = random.nextInt(txtnumlines);
// takes a random number, that number will be used to get the name from the txt line
int i = 0;
String RandomName = "";
while(fileReloaded.hasNext())
{
String aLine = fileReloaded.nextLine();
if (i == randomintname) Randomname = aLine;
i++;
}
// Now you can do whatever you want with the Randomname variable. You might want to lowercase the first letter, however. :p
}
Reading all lines
String[] lines = new Scanner(
MyClass.class.getClassLoader().getResourceAsStream("Names.txt"),
StandardCharsets.UTF_8.name()
).next().split("\\A");
Extract random line
Random random = new Random();
String randomLine = lines[random.nextInt(lines.length)].trim();

Java file to 2D array

I'm trying to create a 2D array from a .txt file, where the .txt file looks something like this:
xxxx
xxxx
xxxx
xxxx
or something like this:
xxx
xxx
xxx
So I need to handle multiple sizes of a 2D array (Note: Each 2D array will not always be equal x and y dimensions). Is there anyway to initialize the array, or get the number of characters/letters/numbers per line and number of columns? I do not want to use a general statement, something like:
String[][] myArray = new Array[100][100];
And then would filling the array using filewriter and scanner classes look like this?
File f = new File(filename);
Scanner input = new Scanner(f);
for(int i = 0; i < myArray[0][].length; i++){
for(int j = 0; j < myArray[][0].length, j++){
myArray[i][j] = input.nextLine();
}
}
You have several choices as I see it:
Iterate through the file twice, the first time getting the array parameters, or
Iterate through it once, but fill up a List<List<SomeType>> possibly instantiating your Lists as ArrayLists. The latter will give you much greater flexibility in the short and long run.
(per MadProgrammer) The third option is to re-structure the file to provide the meta data required to make decisions about the size of the array.
For example, using your code,
File f = new File(filename);
Scanner input = new Scanner(f);
List<List<String>> nestedLists = new ArrayList<>();
while (input.hasNextLine()) {
String line = input.nextLine();
List<String> innerList = new ArrayList<>();
Scanner innerScanner = new Scanner(line);
while (innerScanner.hasNext()) {
innerList.add(innerScanner.next());
}
nestedLists.add(innerList);
innerScanner.close();
}
input.close();
Java Matrix can have each line (which is an array) by your size desicion.
You can use: ArrayUtils.add(char[] array, char element) //static method
But before that, you need to check what it the file lines length
Either this, you can also use ArrayList> as a collection which is holding your data

Convex Hull - Reading from input file

I am trying to read the x,y coordinates from a file that has 1000 entries.
This is what I have so far:
int n=4;
Point2D []p = new Point2D[n];
p[0] = new Point2D(4,5);
p[1] = new Point2D(5,3);
p[2] = new Point2D(1,4);
p[3] = new Point2D(6,1);
I can open the file like this:
Scanner numFile = new Scanner(new File("myValues.txt"));
ArrayList<Double> p = new ArrayList<Double>();
while (numFile.hasNextLine()) {
String line = numFile.nextLine();
Scanner sc = new Scanner(line);
sc.useDelimiter(" ");
while(sc.hasNextDouble()) {
p.add(sc.nextDouble());
}
sc.close();
}
numFile.close();
But I do not know how to create arrays with two values each time.
Please let me know if you need more information.
All you really need to do is create a Point2D object (using the coords in your .txt file) at each iteration of the loop, then add that object to your array list of Point2D objects:
For example:
ArrayList<Points2D> p = new ArrayList<>();
Scanner numFile = new Scanner(new File("myValues.txt"));
String pointOnLine = numFile.readLine();
while (numFile != null) //if line exists
{
String[] pointToAdd = pointOnLine.split(" +"); //get x y coords from each line, using a white space delimiter
//create point2D object, then add it to the list
Point2D pointFromFile = new Point2D(Integer.parseInt(pointToAdd[0]), Integer.parseInt(pointToAdd[1]));
p.add(pointFromFile);
numFile = numFile.readLine(); //assign numFile to the next line to be read
}
The tricky part (and the part you're stuck at I'm assuming), is extracting the individual x and y-coordinates from the file.
What I have done above was use the .split() method to turn every single line into a string array of each number on the entire line, separated by a white space. Since each line should only contain two numbers (x and y), the array size will be 2 (elements 0 and 1 respectively).
From there, we simply get the first element in the string array (the x-coordinate), and the second element (the y-coordinate), and then parse those strings into integers.
Now that we have isolated the x and y from each line, we use them to create the Point2D object, and then add that object to the array list.
Hope this clarifies things

How do I get the total number of elements in a file into an array?

I need to make a program which reads a file in a method. The file is a "data.txt" type and will have a list of numbers (double data type) with one number on each line.
Ex:
23.4
12.3
111.4533
I need to then put this in an array (NOT a 2D array)and return it to the main method.
I used filename.length() but it makes the array size larger than it should be and I'm getting an array out of bounds error.
I can initialize the array in a while loop, but it keeps saying I need to declare the size of the array first and I don't know how to do this. So I tried just using a while loop to get the number of lines and then using another loop to input the elements but it won't let me return the array to the main method without initializing the array. Here's what I have so far:
java.io.File file = new java.io.File(file);
int arraySize = (int)file.length();
int size = 0;
int i = 0;
try{
Scanner input = new Scanner(file);
while(input.hasNextLine()){
size++;
}
double [] array;
array1 = new double [size];
while(input.hasNext()){
array[i] = input.nextDouble();
i++;
}
Any suggestions? I'm really stuck on this. Thanks.
Two possible solutions:
a) Use a collection which grows on demand instead of using a fixed array (e.g., ArrayList). You can also convert it afterwards into an array again.
b) Close the scanner and open the file again after you counted the number of lines.
The problem right now is that you are not redefining the Scanner, so after you determine the size, the Scanner is at the end of the file and so there are no more doubles to be read in.
Also, when determining the size, you need to actually read in the line each loop so you skip to new lines, or else I think you will have an infinite loop. If you never read in a line, it always has more.
Try this (tested and works):
java.io.File file = new java.io.File(file);
int size = 0;
int i = 0;
try {
Scanner input = new Scanner(file);
while(input.hasNextLine()){
input.nextLine(); // have to change the lines
size++;
}
double [] array;
array = new double [size];
// reopen the file so you start from the beginning again
input = new Scanner(file);
while(input.hasNext()){
array[i] = input.nextDouble();
i++;
}
// print out the array
for (double d : array) {
System.out.println(d);
}
} catch (Exception e) {
e.printStackTrace();
}
Or you could just use an ArrayList which has no defined size (you can .add elements to it and so you don't need to know the size beforehand to populate it). And then just convert the ArrayList to a regular array afterword if you wanted to.
Try this:
java.io.File file = new java.io.File("C:\\Users\\Mike\\Desktop\\data.txt");
try {
Scanner input = new Scanner(file);
ArrayList<Double> list = new ArrayList<Double>(); // define empty ArrayList
while(input.hasNextLine()) {
list.add(input.nextDouble()); // have to change the lines
}
// convert ArrayList to array
// (although you don't need to do this if you're fine with an ArrayList)
double[] array = new double[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
// print out the array
for (double d : array) {
System.out.println(d);
}
} catch (Exception e) {
e.printStackTrace();
}
Assuming your filename variable is a String of the file's name then filename.length is only giving you the total characters in the name. If you have called your File object filename then filename.length() returns a long of the file's length in bytes and not the number of rows inside it.
To get the number of lines in a file you can refer to this question for many possible answers: Number of lines in a file in Java
But more likely you want to use an expandable Collection instead of a fixed length array as you do not then need to calculate and read the whole file before you begin using it. Something like an ArrayList could be ideal. But it does depend on your use case.
You can always convert the ArrayList back to an Array afterwards:
String[] lines = lineList.toArray(new String[lineList.size()]);
I would recommend using an ArrayList. That way you don't have to be aware of the size while creating the array. As other's have said, you can convert to a array after you are done adding values to the ArrayList.
Assuming your data.txt file has your doubles line by line with no spaces. you could use the following code:
ArrayList <Double> doubleArray = new ArrayList<Double>();
Scanner fileScan = null;
try {
fileScan = new Scanner(new File("/path/to/file"));
while (fileScan.hasNextDouble()){
doubleArray.add(fileScan.nextDouble());
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
use below code
read line by line of text file and parse each line element to double
add double parsed value to arraylist
convert arraylist to array.
String fileName=null;
File file = null;
try {
fileName="path/filename.txt";
file = new File(fileName);
} catch (Exception e) {
System.out.println(e.getMessage());
// TODO: handle exception
}
List<Double> elements = new ArrayList<>();
try{
Scanner input = new Scanner(file);
while(input.hasNextLine()){
elements.add(Double.parseDouble(input.nextLine()));
}
double[] ret = new double[elements.size()];
for(int index = 0;index < ret.length;index++)
ret[index] = elements.get(index);
System.out.println(ret);
System.out.println("end");
}
catch(Exception e){
}

Java: FileRead question

How would you write this code?
This particular question is about a maze game that has an arraylist of occupants which are Explorers (you), Monsters (touching will kill you), and Treasures. The game uses blocks of square objects in which these occupants reside in. The particular thing I want to do is file reading which can export the current configuration of the maze or import them as a txt file.
The specs:
First read in the rows and cols of the Maze to create a Square[][] of the appropriate size. Then construct and read in all the Squares/Occupants.
For Squares, the Maze will first determine that the line starts with "Square". It will then read in the row and col of the Square and use that information to construct a Square object. Finally it will pass the rest of the Scanner to the Square's toObject method so it can initialize itself.
For all other Occupants, the Maze will determine what kind of Occupant it is and construct the appropriate object using the constructor that only takes a Maze. It will not read the row or the col from the Scanner, but simply pass the Scanner on to the toObject method of the newly created object.
This is code that I have so far which could be wrong:
public void readMazeFromFile(String fileName) throws IOException, FileNotFoundException, MazeReadException
{
Scanner fileSc = new Scanner(new File(fileName));
String line = fileSc.nextLine(); //whats on the line, will be overwritten
Scanner lineSc = new Scanner(line);
String temp;
lineSc.useDelimiter(",");
int lineNum = 1; //every time you scan a line out, do lineNum++
int r1, r2, r3, r4, c1, c2, c3, c4;
rows = fileSc.nextInt();
cols = fileSc.nextInt();
Square hi = new Square(rows, cols);
line = fileSc.nextLine();
while ( line != null)
{
line = lineSc.nextLine();
lineSc = new Scanner(line);
if( lineSc.equals("Square"))
{
r1 = lineSc.nextInt();
c1 = lineSc.nextInt();
hi.toObject(lineSc);
}
if (lineSc.equals("Explorer"))
{
explorer.toObject(lineSc);
}
if (lineSc.equals("Treasure"))
{
Treasure.toObject(lineSc);
}
lineNum++;
}
Here is sample output:
5,5
Square,0,0,true,false,false,true,true,true
Square,0,1,true,false,true,false,true,true
Square,0,2,true,false,true,false,false,false
Square,0,3,true,false,false,false,false,false
Square,0,4,true,true,false,false,false,false
Square,1,0,false,false,true,true,true,true
Square,1,1,true,false,true,false,false,false
Square,1,2,true,true,false,false,false,false
Square,1,3,false,true,false,true,false,false
Square,1,4,false,true,false,true,false,false
Square,2,0,true,false,false,true,false,false
Square,2,1,true,false,true,false,false,false
Square,2,2,false,true,false,false,false,false
Square,2,3,false,true,false,true,false,false
Square,2,4,false,true,false,true,false,false
Square,3,0,false,true,false,true,false,false
Square,3,1,true,false,false,true,false,false
Square,3,2,false,true,false,false,false,false
Square,3,3,false,true,true,true,false,false
Square,3,4,false,true,false,true,false,false
Square,4,0,false,true,true,true,false,false
Square,4,1,false,true,true,true,false,false
Square,4,2,false,false,true,true,false,false
Square,4,3,true,false,true,false,false,false
Square,4,4,false,true,true,false,false,false
Explorer,0,0,Scary Name
Treasure,4,4,true
Treasure,2,2,false
Monster,4,4
Monster,3,3
What would you write for this section?
This is a skeleton that you can start with. You really don't need anything more than a Scanner here; it can do everything that you'd need to scan the input and do the conversion, etc. You want to use its next(), nextInt(), nextBoolean() and nextLine() methods.
Scanner in = new Scanner(new File(filename));
in.useDelimiter("\\s+|,");
int rows = in.nextInt();
int cols = in.nextInt();
// construct the array
while (in.hasNext()) {
String type = in.next();
int r = in.nextInt();
int c = in.nextInt();
// read more depending on type
}
Use a
FileReader
on the file and then attach a
StreamTokenizer
to that, far more efficient :)

Categories