I have a text file and i am trying to convert every line into an ArrayList. Then i have to take a random line from this text.file and display it on new JOptionPane.
I am trying to implement it in the for-loop but it always appears only the first line from my text.file. Thank you very much and here is my code.
public void actionPerformed(ActionEvent e) {
ArrayList<String> allQuestions = new ArrayList<String>();
ArrayList<String> allRandomSelectedQuestions = new ArrayList<String>();
File file = new File("C:/Users/User/Documents/NetBeansProjects/SummerExamProject/src/Questions2.txt");
int numberOfRandomQuestions = 16;
try {
//Read line by line from the file
Scanner scan = new Scanner(file);
while (scan.hasNextLine()) {
String line = scan.nextLine();
// System.out.println(line);
JOptionPane.showMessageDialog(null, line.replace("/", "\n"));
scan.close();
allQuestions.add(line);
}
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
for(int i = 0; i < numberOfRandomQuestions; i++){
Random randNum = new Random();
int randQuestionIndex = randNum.nextInt(numberOfRandomQuestions);
String randomQuestion = allQuestions.get(randQuestionIndex);
allRandomSelectedQuestions.add(randomQuestion);
}
}
This line...
scan.close();
Is inside your while loop, so it closes the file after reading a line the first time it goes through the loop.
Moving it to after the loop (i.e. after the close culry-brace) ought to fix it.
The problem is this: scan.close();. You are closing your scanner in the same loop you are using for reading. Moving it outside the loop body should solve the problem.
Call close method after the while loop. What is happening that, you close after the first line. so the while loop stops after only one time.
while (scan.hasNextLine()) {
String line = scan.nextLine();
//System.out.println(line);
JOptionPane.showMessageDialog(null, line.replace("/", "\n"));
allQuestions.add(line);
}
scan.close();
Try this. Hope it helps.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class StackTest {
public static void main(String[] args) {
actionPerformed();
}
public static void actionPerformed() {
ArrayList<String> allQuestions = new ArrayList<String>();
File file = new File("D:/me/test.txt");
int numberOfRandomQuestions = 10;
try {
// Read line by line from the file
Scanner scan = new Scanner(file);
while (scan.hasNextLine()) {
String line = scan.nextLine();
allQuestions.add(line);
}
scan.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
for (int i = 0; i < numberOfRandomQuestions; i++) {
Random randNum = new Random();
int randQuestionIndex = randNum.nextInt(numberOfRandomQuestions);
System.out.println();
String randomQuestion = allQuestions.get(randQuestionIndex);
JOptionPane.showMessageDialog(null, randomQuestion.replace("/", "\n"));
}
}
}
Related
Basically, I had to create a scanner for a given file and read through the file (the name is input through the terminal by the user) once counting the number of lines in the file. Then after, I had to create an array of objects from the file, of the correct size (where the num of lines comes in). Then I had to create another scanner for the file and read through it again, storing it in the array I created. And lastly, had to return the array in the method.
My problem is I cannot seem to get the second scanner to actually store the file objects in the array.
I've tried using .nextLine inside a for loop that also calls the array, but it doesn't seem to be working.
public static Data[] getData(String filename) {
Scanner input = new Scanner(new File(filename));
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
System.out.println(count);
Data[] data = new Data[count];
Scanner input1 = new Scanner(new File(filename));
while (input1.hasNextLine()) {
for (int i = 0; i < count; i++) {
System.out.println(data[i].nextLine);
}
}
return data;
}
I expect the output to successfully read the input file so that it can be accessed by other methods that I have created (not shown).
You should definitely use an IDE if you don't have one, try intellij... There you have autocompletion and syntax checking and much more.
It is not clear what you want to do in your for loop, because there are several mistakes, for example the readline() function works only with the scanner objekt, so you can do input.nextline() or input1.nextline()`...
so I just show you, how you can get the Data from a file with Scanner:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Readfile {
public static void getData(String filename) throws FileNotFoundException {
ArrayList<String> test = new ArrayList<>(); //arraylist to store the data
Scanner inputSc = new Scanner(new File(filename)); //scanner of the file
while (inputSc.hasNextLine()) {
String str = inputSc.nextLine();
System.out.println(str); //print the line which was read from the file
test.add(str); //adds the line to the arraylist
//for you it would be something like data[i] = str; and i is a counter
}
inputSc.close();
}
public static void main(String[] args) {
try {
getData("/home/user/documents/bla.txt"); //path to file
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
You don't need to read thru the file twice - just use an ArrayList to hold the data that's coming in from the file, like this, and then return Data[] at the end:
public static Data[] getData(String filename) {
List<Data> result = new ArrayList<>();
try (Scanner input = new Scanner(new File(filename))){
while (input.hasNextLine()) {
Data data = new Data(input.nextLine());
result.add(data);
}
}
return result.toArray(new Data[0]);
}
Not clear what Data.class do you mean, if you switch it to String, the problem obviously would be in this line
System.out.println(data[i].nextLine);
if you want to assign and print simultaneously write this
for (int i = 0; i < count; i++) {
data[i] = input1.next();
System.out.println(data[i]);
}
and dont forget to close your Scanners, better use try-with-resources.
If your Data is your custom class you'd better learn about Serialization-Deserialization
Or use some ObjectMapper-s(Jackson, for example) to store your class instances and restore them.
Your way of opening the file just to count the lines and then again looping through its lines to store them in the array is not that efficient, but it could be just a school assignment.
Try this:
public static Data[] getData(String filename) {
Scanner input = null;
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
int count = 0;
while (input.hasNextLine()) {
input.nextLine();
count++;
}
input.close();
System.out.println(count);
Data[] data = new Data[count];
try {
input = new Scanner(new File(filename));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
for (int i = 0; i < count; i++) {
Data d = new Data(input.nextLine(), 0, 0);
data[i] = d;
System.out.println(data[i].name);
}
input.close();
return data;
}
After the 1st loop you must close the Scanner and reopen it so to start all over from the first line of the file.
I have a method that needs to select a random word from a txt file, but it only works some of the time.
The content of the file is as follows:
Broccoli
Tomato
Kiwi
Kale
Tomatillo
My code:
import java.util.Random;
import java.util.Scanner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public String getRandomItem(){
Scanner fileIn = null;
String temp = "";
int r = randomGenerator.nextInt(5) + 1;
byte i = 0;
try {
fileIn = new Scanner(new FileInputStream("bundles.txt"));
} catch (FileNotFoundException e) {
System.out.println("File not found.");
System.exit(0);
}
while(i <= 5){
temp = fileIn.nextLine();
if(i == r){
break;
}
i++;
}
fileIn.close();
return temp;
}
Could someone please tell me where I am going wrong?
I would use Files.readAllLines(Path) to read all the lines once, and then get a single random word from that. Something like,
private static List<String> lines = null;
static {
try {
lines = Files.readAllLines(new File("bundles.txt").toPath());
} catch (IOException e) {
e.printStackTrace();
}
}
private Random rand = new Random();
public String getRandomItem() {
return lines.get(rand.nextInt(lines.size()));
}
I have a text file that looks like this:
House1 25456 22456 54564 54564
House2 54788 54756
House(it could be up t 1500 houses)
and I want it to look like this:
House1 25456
House1 22456
House1 54564
House1 54564
House2 54788
House2 54756
House(again same principle)
code
public class Houses {
public static void main(String[] args) {
UsingScanner();
}
public static void UsingScanner(){
try{
Scanner sc = new Scanner (new File("C:\\Test.txt"));
while (sc.hasNextLine()){
System.out.println(sc.nextLine());
}
}catch(Exception e){
System.out.println("Ups! you got a problem");
}
}
}
Use String.split() to extract the house numbers. Then loop through them to print it (or collect it to a StringBuilder if needed). eg:
while (sc.hasNextLine()){
String[] tokens = sc.nextLine().split("\\s+");
String houseName = tokens[0];
for(int i=1; i< tokens.length ; i++)
System.out.println(houseName + " " + tokens[i]);
}
String[] parts = sc.nextLine().split();
for (int i=1;i<parts.length;i++){
out.write(parts[0]+" "+parts[i]);
}
Assuming out is an OutputStream.
I tried to keep it as simpler as possible and with less possible changes with respect to your original code:
import java.io.File;
import java.io.FileWriter;
import java.util.Scanner;
public class Houses {
public static void main(String[] args) {
UsingScanner();
}
public static void UsingScanner() {
try {
Scanner sc = new Scanner(new File("C:\\Test.txt"));
//fw is to write you desired result into the Output.txt file
FileWriter fw = new FileWriter(new File("C:\\Output.txt"));
while (sc.hasNextLine()) {
//split your line by spaces into an array of Strings
String[] splitted = sc.nextLine().split(" ");
//at index zero of the array there is always the house name
for (int k = 1; k < splitted.length; k++) { //so start the loop from index 1
//loop every numeric item of a line, write the house name and the numeric item
fw.write(splitted[0] + " " + splitted[k] + System.getProperty("line.separator"));
}
//step to the next house name (another line)
}
fw.close();
} catch (Exception e) {
System.out.println("Ups! you got a problem");
}
}
}
I'm working on a Java program in which I must read the contents of a file and then print each lines reverse. For example the text:
Public Class Helloprinter
Public static void
would print the following after running my reverse program:
retnirPolleh ssalc cilbup
diov citats cilbup
Here's what I got so far:
public static void main(String[] args) throws FileNotFoundException {
// Prompt for the input and output file names
ArrayList<String> list = new ArrayList<String>();
//String reverse = "";
Scanner console = new Scanner(System.in);
System.out.print("Input file: ");
String inputFileName = console.next();
System.out.print("Output file: ");
String outputFileName = console.next();
// Construct the Scanner and PrintWriter objects for reading and writing
File inputFile = new File(inputFileName);
Scanner in = new Scanner(inputFile);
PrintWriter out = new PrintWriter(outputFileName);
String aString = "";
while(in.hasNextLine())
{
String line = in.nextLine();
list.add(line);
}
in.close();
for(int i = 0; i <list.size(); i++)
{
aString = list.get(i);
aString = new StringBuffer(aString).reverse().toString();
out.printf("%s", " " + aString);
}
out.close();
}
}
EDIT:
With Robert's posting it helped put me in the right direction. The problem is that with that is that it doesn't keep the lines.
Public Class Helloprinter
Public static void
becomes after running my program:
retnirPolleh ssalc cilbup diov citats cilbup
it needs to keep the line layout the same. so it should be:
retnirPolleh ssalc cilbup
diov citats cilbup
Your problem is in the line
out.printf("%s", " " + aString);
This doesn't output a newline. I'm also not sure why you are sticking a space in there.
It should be either:
out.println( aString );
Or
out.printf("%s%n", aString);
In your last loop why don't you just iterate through the list backwards? So:
for(int i = 0; i <list.size(); i++)
Becomes:
for(int i = list.size() - 1; i >=0; i--)
It seems like you already know how to read a file, so then call this method for each line.
Note, this is recursion and it's probably not the most efficient but it's simple and it does what you want.
public String reverseString(final String s) {
if (s.length() == 0)
return s;
// move chahctrachter at current position and then put it at the end of the string.
return reverseString(s.substring(1)) + s.charAt(0);
}
Just use a string builder. You were on the right trail. Probably just needed a little help. There is no "one way" to do anything, but you could try something like this:
Note: Here is my output: retnirPolleh ssalc cilbup diov citats cilbup
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
ArrayList<String> myReverseList = null;
System.out.println("Input file: \n");
Scanner input = new Scanner(System.in);
String fileName = input.nextLine();
System.out.println("Output file: \n");
String outputFileName = input.nextLine();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(fileName));
String text = null;
myReverseList = new ArrayList<String>();
StringBuilder sb = null;
try {
while ((text = br.readLine()) != null) {
sb = new StringBuilder();
for (int i = text.length() - 1; i >= 0; i--) {
sb.append(text.charAt(i));
}
myReverseList.add(sb.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Writer writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFileName), "utf-8"));
for (String s : myReverseList) {
writer.write("" + s + "\n");
}
} catch (IOException ex) {
// report
} finally {
try {
writer.close();
} catch (Exception ex) {
}
}
}
}
I'm trying to get saved data in a text file to an array to use it in my code and then search this array for a string submitted from the user from the GUI , but for some reason I print out the data in the array it is all null. here's the code !!
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class IO {
File f = new File("DB.txt");
PrintWriter write;
Scanner input;
String[][] data;
String nameToSearch;
// search constructor
public IO(String name) {
super();
nameToSearch = name;
try {
input = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found please restart the program");
}
data = new String[linesCounter()][2];
int i = 0;
while (input.hasNext()) {
data[i][0] = input.nextLine();
data[i][1] = input.nextLine();
i++;
}
}
public IO(String name, String number) {
try {
write = new PrintWriter(new FileWriter(f, true));
} catch (IOException e) {
System.out.println("Error");
}
write.println(name);
write.println(number);
write.close();
}
int linesCounter() {
try {
input = new Scanner(f);
} catch (FileNotFoundException e) {
System.out.println("File not found please restart the program");
}
int counter = 0;
while (input.hasNext()) {
input.nextLine();
counter++;
}
return counter / 2;
}
int contactFinder() {
int i = 0;
while (input.hasNext()) {
if (data[i][0].equalsIgnoreCase(nameToSearch))
return i;
i++;
}
return -1;
}
String nameGetter() {
return data[contactFinder()][0];
}
String numGetter() {
return data[contactFinder()][1];
}
}
It looks like you read all the lines in from the file to count how many lines there are, and then when you go to read the data, you're starting from where you left off, which would be the end of the file.
It's also worth noting that you can use commons-io FileUtils to easily read all the lines from a file.
For example:
List<String> lines = FileUtils.readLines(f);
String[][] data = new String[lines.length][2];
for (int i = 0; i < lines.size(); i++) {
data[i][i % 2] = lines.get(i);
}
If you also don't want to use a (very useful) third party library, you could load up the data pretty simply with:
List<String> lines = new ArrayList<String>();
Scanner input = new Scanner(f);
while (input.hasNextLine()) {
lines.add(input.nextLine());
}
input.close();
Then go into the array population.
I would advice you to use RandomAccessFile. This has methods such as readLine() to read the line and seek(long pos) to set the file read pointer. You may use seek(0L) to restart the reading of the file.