I'm just starting to learn Java and I'm trying to complete this exercise.
I've understood how to extract the information from the txt file (I think) using scanner (we're only supposed to change the method body). However I'm not sure of the correct syntax to transfer the information to an array.
I realise it must be very simple, but I can't seem to figure it out. Could someone please point me in the right direction in terms of syntax and elements needed? Thank you in advance!
import java.util.Scanner;
import java.io.FileReader;
import java.io.IOException;
public class Lab02Task2 {
/**
* Loads the game records from a text file.
* A GameRecord array is constructed to store all the game records.
* The size of the GameRecord array should be the same as the number of non-empty records in the text file.
* The GameRecord array contains no null/empty entries.
*
* #param reader The java.io.Reader object that points to the text file to be read.
* #return A GameRecord array containing all the game records read from the text file.
*/
public GameRecord[] loadGameRecord(java.io.Reader reader) {
// write your code after this line
Scanner input = new Scanner(reader);
for (int i=0; input.hasNextLine(); i++) {
String inputRecord = input.nextLine();
input = new Scanner(inputRecord);
// array?
}
return null; // this line should be modified/removed after finishing the implementation of this method.
}
}
In case you already have a String of the file content, you can say:
String[] words = content.split("\\s");
You can parse your String like this:
private ArrayList<String> parse(BufferedReader input) throws CsvException {
ArrayList<String> data = new ArrayList<>();
final String recordDelimiter = "\\r?\\n|\\r";
final String fieldDelimiter = "\\t";
Scanner scanner = new Scanner(input);
scanner.useDelimiter(recordDelimiter);
while( scanner.hasNext() ) {
String line = scanner.next();
data.add(line);
}
return data;
}
The input text will be scanned line by line.
You can use an ArrayList<String>, like this:
Scanner s = new Scanner(new File(//Here the path of your file));
ArrayList<String> list = new ArrayList<String>();
while (s.hasNext())
{
list.add(s.nextLine());
}
And if you want to get the value of some item of the ArrayList you just have to make reference with get function, like this:
list.get(//Here the position of the value in the ArrayList);
So, if you want to get all the values of the ArrayList you can use a loop to do it:
for (int i = 0; i < list.size(); i++)
{
System.out.println(list.get(i));
}
And finally close your Scanner:
s.close();
I expect it will be helpful for you!
Assuming your one row in file contains one game only
for (int i=0; input.hasNextLine(); i++) {
String inputRecord = input.nextLine();
input = new Scanner(inputRecord);
String line=input.nextLine();
arr[i]=line;
}
return arr;
Related
I am a beginner in programming. I am currently learning how to convert texts from notepad into array line by line. An instance of the text in notepad,
I am a high school student
I love banana and chicken
I have 2 dogs and 3 cats
and so on..
In this case, the array[1] will be string 'I love banana and chicken'.
The lines in the notepad can be updated and I want the array to be dynamic/flexible. I have tried to use scanner to identify each of the lines and tried to transfer them to array. Please refer to my code:
import java.util.*;
import java.io.*;
import java.util.Scanner;
class Test
{
public static void main(String[] args)
throws Exception
{
File file = new File("notepad.txt");
Scanner scanner = new Scanner(file);
String line;
int i = 0;
int j = 0;
while (scanner.hasNextLine()) {
i++;
}
String[] stringArray = new String[i];
while (scanner.hasNextLine()) {
line = scanner.nextLine();
stringArray[j] = line;
j++;
}
System.out.println(stringArray[2]);
scanner.close();
}
}
I am not sure why there is runtime-error and I tried another approach but still did not produce the result that I want.
The first loop would be infinite because you check if the scanner has a next line, but never advance its position. Although using a Scanner is fine, it seems like a lot of work, and you could just let Java's nio package do the heavy lifting for you:
String[] lines = Files.lines(Paths.get("notepad.txt")).toArray(String[]::new);
You can simply do it by creating an ArrayList and then converting it to the String Array.
Here is a sample code to get you started:
public static void main(String[] args) throws FileNotFoundException {
Scanner in = new Scanner(new File("notepad.txt"));
List<String> outputList = new ArrayList<>();
String input = null;
while (in.hasNextLine() && null != (input = in.nextLine())) {
outputList.add(input);
}
String[] outputArray = new String[outputList.size()];
outputArray = outputList.toArray(outputArray);
in.close();
}
Since you want array to be dynamic/flexible, I would suggest to use List in such case. One way of doing this -
List<String> fileLines = Files.readAllLines(Paths.get("notepad.txt"));
I am attempting to create a program that can read a textfile and create an arraylist of objects based off the data (among other things). Most of the text is pretty straight, and is comprised of two double numbers like so:
454.56 3.4
3321.7 .0023
However, some of the lines of text are missing a number at the end and only contain one double like this:
3222.5
This is a simplified version of the code that I have so far:
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class objectGenerator {
public double firstDouble;
public double secondDouble;
objectGenerator(double 1, double 2) {
firstDouble = 1;
secondDouble = 2;
}
public static void main(String[] args) {
String fileName = "data.txt";
Scanner inputStream = null;
try {
inputStream = new Scanner(new File(fileName));
} catch (FileNotFoundException e) {
System.out.println("Error opening the file " +
fileName);
System.exit(0);
}
List<objectGenerator> objects = new ArrayList<objectGenerator>();
while (inputStream.hasNextLine()) {
String line = inputStream.nextLine();
String[] data = line.split(" ");
objectGenerator object = new objectGenerator(Double.parseDouble(data[0]), Double.parseDouble(data[1]));
objects.add(object);
}
inputStream.close();
//example text file
//544.7 7.4
//34.5
}
}
Running the following code will produce an error message due to the fact of how the text file is missing a double at the end of the second line. I am unsure of how to get around this issue and would appreciate any help that I could get.
As a side note, it would be very beneficial if there were some way for me to fill in a default value for the empty space that was left by the text file when I am populating the arraylist. The final text file that I will be working with could potentially contain hundreds of lines of code, so it will be nice if there was a way too fill in a default value for all the empty spaces when I am creating the objects.
Here is how I would refactor your while loop:
static final double DEFAULT_DATA = -1d; // replace with your desired default value
while (inputStream.hasNextLine()) {
String line = inputStream.nextLine();
String[] data = line.split(" ");
objectGenerator object = null;
if (data.length == 1 && data[0].equals("")) { // empty line
object = new objectGenerator(DEFAULT_DATA, DEFAULT_DATA);
}
else if (data.length == 1) { // only one number
object = new objectGenerator(Double.parseDouble(data[0]), DEFAULT_DATA);
}
else { // two numbers
object = new objectGenerator(Double.parseDouble(data[0]),
Double.parseDouble(data[1]));
}
// you may want to check if (object == null) here to cover any weird edge cases
objects.add(object);
}
By the way, Java naming conventions state that the first letter of class names should appear in UPPERCASE. So I would change the name of your class to ObjectGenerator, with a capital O.
create overloaded constructor for your objectGenerator
objectGenerator(double a){
this(a, 0);
}
objectGenerator(double a, double b){
firstDouble = a;
secondDouble = b;
}
I just assumed to keep secondDouble value to be zero if not found in text file
Now you can create objectGenerator like this :
objectGenerator object = new data.length == 1 ? objectGenerator(Double.parseDouble(data[0])) : new objectGenerator(Double.parseDouble(data[0]),Double.parseDouble(data[1])) ;
if you are using java 8
You can create constructor with variable arguments
objectGenerator(double...arr){
firstDouble = arr[0];
secondDouble = arr.length > 1 ? arr[1] : 0;
}
Say you have a text file with "abcdefghijklmnop" and you have to add 3 characters at a time to an array list of type string. So the first cell of the array list would have "abc", the second would have "def" and so on until all the characters are inputted.
public ArrayList<String> returnArray()throws FileNotFoundException
{
int i = 0
private ArrayList<String> list = new ArrayList<String>();
Scanner scanCharacters = new Scanner(file);
while (scanCharacters.hasNext())
{
list.add(scanCharacters.next().substring(i,i+3);
i+= 3;
}
scanCharacters.close();
return characters;
}
Please use the below code,
ArrayList<String> list = new ArrayList<String>();
int i = 0;
int x = 0;
Scanner scanCharacters = new Scanner(file);
scanCharacters.useDelimiter(System.getProperty("line.separator"));
String finalString = "";
while (scanCharacters.hasNext()) {
String[] tokens = scanCharacters.next().split("\t");
for (String str : tokens) {
finalString = StringUtils.deleteWhitespace(str);
for (i = 0; i < finalString.length(); i = i + 3) {
x = i + 3;
if (x < finalString.length()) {
list.add(finalString.substring(i, i + 3));
} else {
list.add(finalString.substring(i, finalString.length()));
}
}
}
}
System.out.println("list" + list);
Here i have used StringUtils.deleteWhitespace(str) of Apache String Utils to delete the blank space from the file tokens.and the if condition inside for loop to check the substring for three char is available in the string if its not then whatever character are left it will go to the list.My text file contains the below strings
asdfcshgfser ajsnsdxs in first line and in second line
sasdsd fghfdgfd
after executing the program result are as,
list[asd, fcs, hgf, ser, ajs, nsd, xs, sas, dsd, fgh, fdg, fd]
public ArrayList<String> returnArray()throws FileNotFoundException
{
private ArrayList<String> list = new ArrayList<String>();
Scanner scanCharacters = new Scanner(file);
String temp = "";
while (scanCharacters.hasNext())
{
temp+=scanCharacters.next();
}
while(temp.length() > 2){
list.add(temp.substring(0,3));
temp = temp.substring(3);
}
if(temp.length()>0){
list.add(temp);
}
scanCharacters.close();
return list;
}
In this example I read in all of the data from the file, and then parse it in groups of three. Scanner can never backtrack so using next will leave out some of the data the way you're using it. You are going to get groups of words (which are separated by spaces, Java's default delimiter) and then sub-stringing the first 3 letters off.
IE:
ALEXCY WOWZAMAN
Would give you:
ALE and WOW
The way my example works is it gets all of the letters in one string and continuously sub strings off letters of three until there are no more, and finally, it adds the remainders. Like the others have said, it would be good to read up on a different data parser such as BufferedReader. In addition, I suggest you research substrings and Scanner if you want to continue to use your current method.
I'm trying to wrap my head around a problem I have in a programming set.
We're supposed to write code that reads from a file and prints it out. I get that, I can do it.
What he wants us to do is have it print out in reverse.
the file reads:
abc
123
987
He wants:
987
123
abc
The code, as it is, is as follows:
{
FileReader n=new FileReader("F:\\Java\\Set 8\\output1.txt");
Scanner in=new Scanner(n);
int l;
while (in.hasNext())
{
l=in.nextInt();
System.out.println(l);
}
in.close();
}
}
Yes, I am using java.io.*; and Scanner.
What would be the simplest way to do this?
EDIT EDIT EDIT
Here's the improved code, where I try to put it into an array.
The data in the array isn't printing out.
public static void main(String[] args) throws IOException
{
int[]Num=new int[20];
Scanner in=new Scanner(new FileReader("F:\\Java\\Set 8\\output1.txt"));
int k;
for (k=0;k<20;k++)
{
Num[k]=in.nextInt();
}
//in.close();
for (k=20;k<20;k--)
{
System.out.print(+Num[k]);
}
//in.close();
}
The most simplest way is to construct a List and add each line to the list while reading from the file. Once done, print the list items in reverse.
Here is my version of code for your problem.
public static void main(String[] args) throws FileNotFoundException {
FileReader n = new FileReader("/Users/sharish/Data/abc.xml");
Scanner in = new Scanner(n);
ArrayList<String> lines = new ArrayList<String>();
while (in.hasNext()) {
lines.add(in.nextLine());
}
in.close();
for (int i = lines.size() - 1; i >= 0; i--) {
System.out.println(lines.get(i));
}
}
Use Stack.
public static void displayReverse() throws FileNotFoundException {
FileReader n=new FileReader("C:\\Users\\User\\Documents\\file.txt");
Scanner in=new Scanner(n);
Stack<String> st = new Stack<String>();
while (in.hasNext()) {
st.push(in.nextLine());
}
in.close();
while(!st.isEmpty()) {
System.out.println(st.pop());
}
}
If you are permitted the use of third party APIs, Apache Commons IO contains a class, ReversedLinesFileReader, that reads files similar to a BufferedReader (except last line first). Here is the API documentation: http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/ReversedLinesFileReader.html
Another (less efficient) solution is hinted at in the comments. You can read your entire file into an ArrayList, reverse that list (e.g. by pushing its contents onto a stack and then popping it off), and then iterate through your reversed list to print.
EDIT:
Here is a crude example:
ArrayList<String> lines = new ArrayList<String>();
Scanner in = new Scanner(new FileReader("input.txt"));
while (in.hasNextLine())
{
lines.add(in.nextLine());
}
Use an ArrayList instead of a static array. We don't necessarily know the length of the file in advance so a static array doesn't make sense here. http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
Your example input 123, abc, etc, contains characters as well as ints, so your calls to hasNextInt and nextInt will eventually throw an Exception. To read lines use hasNextLine and nextLine instead. These methods return String and so our ArrayList also needs to store String. http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNextLine()
Once the file is in a list (not a good solution if the file is large - we've read the entire file into memory) we can either reverse the list (if keeping a reversed form around makes sense), or just iterate through it backwards.
for (int i=lines.size()-1; i>=0; i--) // from n-1 downTo 0
{
String line = lines.get(i);
System.out.println( line );
}
public static void main(String[] args) throws Exception{
String fileName = "F:\\Java\\Set 8\\output1.txt";
RandomAccessFile raf = new RandomAccessFile(fileName,"r");
int len = (int) raf.length();
raf.seek(len);
while(len >= 0){
if(len == 0){
raf.seek(0);
System.out.println(raf.readLine());
break;
}
raf.seek(len--);
char ch = (char)raf.read();
if(ch == '\n'){
String str = raf.readLine();
System.out.println(str);
}
}
}
try using org.apache.commons.io.input.ReversedLinesFileReader, it should do what you want.
You could read the lines like you are already doing, but instead of printing them (because that would print them in order and you need it the other way around), add them to some memory structure like a List or a Stack, and then, in a second loop, iterate this structure to print the lines in the needed order.
Using your code and the answers in the comments, here's an example of how you would store the strings into the arraylist and then print them out in reverse (building off of your own code)
{
FileReader n=new FileReader("F:\\Java\\Set 8\\output1.txt");
Scanner in=new Scanner(n);
int l;
ArrayList<String> reversed = new ArrayList<String>(); // creating a new String arraylist
while (in.hasNext())
{
l=in.nextInt();
System.out.println(l);
reversed.add(l); // storing the strings into the reversed arraylist
}
in.close();
// for loop to print out the arraylist in reversed order
for (int i = reversed.size() - 1; i >= 0; i--) {
System.out.println(reversed.get(i));
}
}
}
Using Java 8:
try(PrintWriter out =
new PrintWriter(Files.newBufferedWriter(Paths.get("out.txt")))) {
Files.lines(Paths.get("in.txt"))
.collect(Collectors.toCollection(LinkedList::new))
.descendingIterator()
.forEachRemaining(out::println);
}
I am trying to read a file with 8 columns of data and store each string of data into an array, but I keep getting cannot find symbol error for employee.length. I put 8 elements for each string within the row. Please help me by explaining what I am doing wrong. Code:
Scanner scan = new Scanner(new FileReader ("payrollData.dat"));
String employee[] = new String[8];
while(scan.hasNext())
{
for(int i = 0; i < employee.length(); i++)
{
employee[i] = scan.next();
}
}
System.out.println(employee);8
Its employee.length and not employee.length(). In case of arrays, length is a final variable, not a method.
And use Arrays.toString(employee) to print employees properly.
System.out.println(employee) will just print the reference address.