Java: FileRead question - java
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 :)
Related
How to delimit new line when reading CSV file?
I am trying to read a file where each line has data members, separated by commas, that are meant to populate an object's data members, I tried using the regex "|" symbol to separate "," and "\n" along with "\r" for getting to the new line. However, after reading the first line, the first data member of the second line does not get read right away but rather a "" character gets read beforehand. Am I using the wrong regex symbols? or am I not using the right approach? I read that there are many ways to tackle this and opted to use scanner since seemed the most simple, using the buffer reader seemed very confusing since it seems like it returns arrays and not individual strings and ints which is I'm trying to get. The CSV file looks something like this stringA,stringB,stringC,1,2,3 stringD,stringE,stringF,4,5,6 stringG,stringH,stringI,7,8,9 My code looks something like this //In list class public void load() throws FileNotFoundException { Scanner input = new Scanner(new FileReader("a_file.csv")); object to_add; //To be added to the list input.useDelimiter(",|\\n|\\r"); while (input.hasNext()) { String n = input.next(); //After the first loop run, this data gets the value "" String l = input.next(); //During this second run, this member gets the data that n was supposed to get, "stringD" String d = input.next(); //This one gets "stringE" int a = input.nextInt(); //And this one tries to get "stringF", which makes it crash int c = input.nextInt(); to_add = new object(n, l, d, a, b, c); //Calling copy constructor to populate data members insert(to_add); //Inserting object to the list } input.close(); }
Use Apache Commons CSV. Here is the user guide https://commons.apache.org/proper/commons-csv/user-guide.html
You can do this with OpenCSV and here is a tutorial how to use this library. You can download the library from the Maven Repository. So following is the code what you need to do, Reader reader = Files.newBufferedReader(Paths.get("path/to/csvfile.csv")); CSVReader csvReader = new CSVReader(reader); List<String[]> dataList = new ArrayList<>(); dataList = csvReader.readAll(); reader.close(); csvReader.close(); Object to_add; for (String[] rowData : dataList) { String textOne = rowData[0]; String textTwo = rowData[1]; String textThree = rowData[2]; int numberOne = Integer.parseInt(rowData[3]); int numberTwo = Integer.parseInt(rowData[4]); int numberThree = Integer.parseInt(rowData[5]); to_add = new Object(textOne, textTwo, textThree, numberOne, numberTwo, numberThree); insert(to_add); }
Java: Using Scanner to add item in method
I'm having issues with finding the right order to so my program will work. It's probably quite easy but I'm very new to programming so hope someone can help me! From a file I get input which needs to be read line by line. I have 4 items on the line which need to be read and put into action. I've use the scanner to read the file line by line and then each item. But then when I want to call to items the program doesn't do anything. I'm not sure what I am missing. Example of the input: black 32 move c 4 black 0 move d 4 white 4198 move c 3 void start() { Scanner fileScanner = UIAuxiliaryMethods.askUserForInput().getScanner(); while (fileScanner.hasNext()) { fileScanner.next(); String inputPlayer = fileScanner.next(); int thinkingTime = fileScanner.nextInt(); String inputMoveOrPass = fileScanner.next(); char inputHorizontalCoordinate = fileScanner.next().charAt(0); int x = inputHorizontalCoordinate - 97; int inputVerticalCoordinate = fileScanner.nextInt(); int y = inputVerticalCoordinate - 1; ui.wait(thinkingTime); if (inputPlayer.equals("white")) { ui.place(x, y, ui.WHITE); } else if (inputPlayer.equals("black")) { ui.place(x, y, ui.BLACK); } ui.showChanges(); } }
You seem to read a String from each line of the file before beginning to read input, which doesn't seem to be aligned with what you want to do. Delete or comment out the first call to fileScanner.next() might do the trick. i.e. Scanner fileScanner = UIAuxiliaryMethods.askUserForInput().getScanner(); while (fileScanner.hasNext()) { // fileScanner.next(); String inputPlayer = fileScanner.next(); int thinkingTime = fileScanner.nextInt();
How can you delay object creation until you have read in all parameters?
I'm trying to solve a problem with creating a custom object with multiple parameters, but the parameters have to first be found one by one using a Scanner. So basically, given an input file, where each line will represent a new object with multiple attributes (a county with its name, its crime index, etc.), I am using a Scanner with a while loop to scan the input file line by line, and then within that loop I'm using another while loop and a new Scanner that then scans each word within the line. That way, I can separate all of the object-to-be's attributes and then create the object by passing all of those values into the constructor. What I can't figure out is how to delay the creation of the object until I have every word in each line, since every line in the input file is to be made into an object, with every word in that line being used as a parameter for the object. Does anyone know how this can be done effectively without having to store all the words into an array or something like that? Here's the constructor from the object class that will take all of the words of a line, which are all in proper order, and create a new object for each line in the input file: public CountyItem(String countyName, String countyState, double countyPercentageClintonVoters, double countyResidentMedianAge, int countyResidentMeanSavings, int countyPerCapitaIncome, double countyPercentageBelowPovertyLevel, double countyPercentageVeterans, double countyPercentageFemale, double countyPopulationDensity, double countyPercentageLivingInNursingHomes, int countyCrimeIndexPerCapita){ itemCountyName = countyName; itemCountyState = countyState; itemCountyPercentageClintonVoters = countyPercentageClintonVoters; itemCountyResidentMedianAge = countyResidentMedianAge; itemCountyResidentMeanSavings = countyResidentMeanSavings; itemCountyPerCapitaIncome = countyPerCapitaIncome; itemCountyPercentageBelowPovertyLevel = countyPercentageBelowPovertyLevel; itemCountyPercentageVeterans = countyPercentageVeterans; itemCountyPercentageFemale = countyPercentageFemale; itemCountyPopulationDensity = countyPopulationDensity; itemCountyPercentageLivingInNursingHomes = countyPercentageLivingInNursingHomes; itemCountyCrimeIndexPerCapita = countyCrimeIndexPerCapita; } And here's my program's main method (still unfinished of course) that shows what I'm talking about with my plan to use nested while loops and two separate scanners to first read every line in the input file and then every word in that line: public static void main(String[] args) throws IOException{ //Scanner and FileWriter Scanner inFile = new Scanner(new FileReader("data/test1.txt")); //change this to use different test .txt file FileWriter outFile = new FileWriter("data/output.txt"); //loops through each line in inputl.txt until end is reached while(inFile.hasNextLine()){ String line = inFile.nextLine(); Scanner lineScanner = new Scanner(line); //loops through every word in a given line while(lineScanner.hasNext()){ } lineScanner.close(); } inFile.close(); }
You can use the builder pattern to slowly build up your constructor's dependencies, or you could also just introduce another constructor that takes in a File, and you can move all the logic from your main method into that constructor.
Scanning from a certain, random line of a file in 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 //... }
problems with parsing a text file in Java
I have looked at all the links and cannot seem to get what I am looking for. I have a text file I need to read in. First the text file format: 3 STL NY Chi //all on one line STL NY 575 //on its own line NY Chi 550 //on its own line STL Chi 225 //on its own line I need to read the int into an int variable, say we call it count. Then the actual cities on that same line into an array. The next lines need to read into an array to where the mileage is associated with the array, such as [STL NY]=575. I can only use arrays. No hash tables, list, stacks or queues. Here is what I got so far and honestly it isn't much. I could really use some help for I am pretty stumped on the "howto" on this. import java.io.*; import java.util.*; public class P3 { /** * #param args the command line arguments */ public static int count; public static void main(String[] args) { try { FileInputStream dataFile = new FileInputStream("Data.txt"); //BufferedReader br = new BufferedReader(new InputStreamReader(dataFile)); String line = br.readLine(); } catch (IOException e) { System.err.println ("Unable to open file"); System.exit(-1); } } } I think I'm getting there, but I am getting an error code of: "non-static variable cities cannot be referenced from a static context." I am trying to test my code by printing. Can anyone help me with this printing? I would like to see what is in the arrays to make sure I did it correctly. Here is my code: package p3; import java.io.*; import java.util.*; class citiesDist { String cityOne; String cityTwo; int miles; } class city { String cityName; int numberLinks; citiesDist[] citiesDists; } public class P3 { city[] cities; void initCity(int len) { for (int i = 0; i < len; i++) { cities[i] = new city(); } } void initCitiesDist (int index, int len) { for (int i = 0; i < len; i++) { cities[index].citiesDists[i] = new citiesDist(); } } void parseFile() throws FileNotFoundException, IOException { FileInputStream fstream = new FileInputStream("Data.txt"); DataInputStream in = new DataInputStream(fstream); BufferedReader br = new BufferedReader(new InputStreamReader(in)); int numberCities = Integer.parseInt(br.readLine()); cities = new city[numberCities]; initCity(numberCities); for (int i = 0; i < numberCities; i++) { String line = br.readLine(); int numberLink = Integer.parseInt(line.split(" ")[1]); cities[i].cityName = line.split(" ")[0]; cities[i].numberLinks = numberLink; initCitiesDist (i, numberLink); for (int j = 0; j < numberLink; j++){ line = br.readLine(); cities[i].citiesDists[j].cityOne = line.split(" ")[0]; cities[i].citiesDists[j].cityTwo = line.split(" ")[1]; cities[i].citiesDists[j].miles = Integer.parseInt(line.split(" ")[2]); } } } public static void main(String args[]) { System.out.println("city" + cities.city); } }
If you're ever stumped on code, don't think about the programming language; it only serves to further muddle your logic. (Separate the algorithm from the language.) When you have a clear idea of what you want to accomplish, add your language in (insofar as, "how do I accomplish this particular task?"). Ultimate Goal From your design, your goal is to have a graph relating the distances between each city. It would appear something like this: [STL][NY] [Chi] [STL][0] [575][25] [NY] [575][0] [550] [Chi][25] [550][0] This isn't too terribly difficult to accomplish, in terms of the file input and the Scanner class. First Steps You have to extract the dimensions of your graph (which is a 3 by 3). This is provided for you in the first line of your input file. Getting an integer from a Scanner with a File in it isn't too difficult, just make sure you have the proper classes imported, as well as the proper error handling (either try...catch or throwing the exception). Scanner sc = new Scanner(new File("input.txt")); You'll need two arrays - one for the cities, and one for the distances themselves. We don't know how large they are (you never assume the data in a file, you just assume the form of the data), so we have to get that from the file itself. Luckily, we are given an integer followed by the cities themselves. We will read this integer once and use it in multiple different locations. String[] cities = new String[sc.nextInt()]; int[][] distances = new int[cities.length][cities.length]; for(int i = 0; i < cities.length; i++) { // Surely there's a method in Scanner that returns String that reads the _next_ token... } The Exercise to the Reader You now have your data structure set up and ready to go. What you would need to do from here is bridge the gap between the cities array and distances array. Consider the order in which they arrived in the file, and the order in which we're encountering them. You would be well-served with some methodology or way to answer the question, 'Which came first - STL or NY?' Give it a whirl and see if you can get further.