Villanova University CSC 1051 www.csc.villanova.edu/~map/1051 Dr. Papalaskari Lab 13 Name:________________________ Checked:______ Objectives: In this lab we will learn how to access text files using Scanner to get their contents. We will also use Scanner in other novel ways, including reading data directly from a webpage! Before you begin, create a folder for your Lab 13 files. It is important to save all the data and program files for this lab in the same folder. Part I: Preparation: Submit 4 files: YouVeGotMoreShoes.java, ShoeCollection.java, Shoe.java (Lab 12, part B) and Lab13a.java (see below) through Blackboard by 8:00am the morning of Lab. a. Reading values from a file and storing them in an array In part (d) of Lab 11 we explored how to input values from the user and store them in an array. Review your program Lab11d.java – recall that it uses Scanner to input integer values from the user. Save a copy of this program in your Lab 13 folder, renaming it as Lab13a.java Suppose you have a long list of values stored in a file, and you want to store them in an array of 100 elements. For example, the file: www.csc.villanova.edu/~map/1051/s16/examples/oneHundredInts.txt You would not want to type the numbers in order to enter them in your program interactively! • Download this file and save in your Lab 13 folder. Open it in jGrasp to inspect it. • Make sure the file was not corrupted during download (this happens sometimes)– it should contain 100 numbers and nothing else –check before proceeding. • In Java, you can direct the Scanner to input from a file, instead of from the keyboard. Do this as follows: o In the instantiation of the Scanner object, replace System.in by the file from which you are “reading”, i.e.: Scanner scan = new Scanner(new File("oneHundredInts.txt")); o Import classes from java.io: import java.io.*; o Add “throws IOException” to the heading of your main method: public static void main(String[] args) throws IOException • Since you want to input 100 numbers, you need to enlarge the array to hold 100 integers. Troubleshooting: Remember to double-check that the file oneHundredInts.txt is saved in the same folder as your program and contains the correct data (a list of 100 numbers). Villanova University CSC 1051 www.csc.villanova.edu/~map/1051 Dr. Papalaskari Part II: b. Processing a text file, line by line www.csc.villanova.edu/~map/1051/s16/examples/FileInput.java //*************************************************************** // FileInput.java Author: MAP // Demonstrates the use of Scanner to read text file input. //*************************************************************** import java.util.Scanner; import java.io.*; public class FileInput { //------------------------------------------------------------ // Reads text from a file and prints it in uppercase. //------------------------------------------------------------ public static void main (String[] args) throws IOException { String line; Scanner fileScan; File myFile = new File("sample.txt"); fileScan = new Scanner (myFile); // Read and process each line of the file while (fileScan.hasNext()) { line = fileScan.nextLine(); System.out.println (line.toUpperCase()); } } } 1) Download and compile this program; create a small text file named sample.txt and save it in the same folder as the program (you can create the file directly in JGrasp – under File-> New, choose “Plain text” instead of “Java” for the file type). Run FileInput – what does it do? ____________________________________________________________________ ____________________________________________________________________ 2) Modify it to use the parameter args[0] of main() as the file name. Do this as follows: • Replace the use of File myFile = new File("sample.txt"); with File myFile = new File(args[0]); • In jGrasp, select “Run Arguments” from the Build menu, and provide the file name as an argument (parameter) to main by typing sample.txt in the box that appears above your program. In this way, you can run your program with different files, without modifying the code. Try it with the dataset file for next project: • www.csc.villanova.edu/~map/1051/s16/examples/titanic.txt Villanova University CSC 1051 www.csc.villanova.edu/~map/1051 Dr. Papalaskari c. Scanning from a String Just as we can use a Scanner to input from a file or from System.in, we can also use a Scanner to “input” from a String! 1) Try this code: Lab13c.java //******************************************************************** // Lab13c.java MA Papalaskari // Simple example: scanning from a String //******************************************************************** import java.util.Scanner; public class Lab13c { public static void main(String[] args) { Scanner scan = new Scanner(System.in); System.out.print("Please type 3 words: "); String line = scan.nextLine(); Scanner scanLine = new Scanner(line); String word1 = scanLine.next(); String word2 = scanLine.next(); String word3 = scanLine.next(); System.out.println("Word 1: " + word1); System.out.println("Word 2: " + word2); System.out.println("Word 3: " + word3); } } Run : Lab13c.java – what does it do? ____________________________________________________________________ ____________________________________________________________________ d. Scanning from a String and doing something useful Next, we will create Lab13d.java by modifying Lab13c.java so that it does something more interesting with the input. Our new program will treat the input as a command for a simple numeric computation. For example, the input might be: 55 * 83 We want the program to compute and print the product 4565. First, run Lab13c.java with this input and observe how it picks out the “55”, “*”, “83” as word1, word2, and word3, respectively. Note that the code uses scanLine.next() which produces String tokens and that was fine because word1, word2, and word3 are Strings. But now you want to use the values 55 and 83 as numbers, so the variables have to be of type double (we scanning from a String Villanova University CSC 1051 www.csc.villanova.edu/~map/1051 Dr. Papalaskari could use int, but double will allow you to handle a wider range of values), and you need to obtain their values using scanLine.nextDouble() instead of scanLine.next(). Can you use these ideas to create a simple calculator? Change the prompt from “Please enter 3 words” to “Calculate: ” Note that you can test the value of word2.charAt(0) to see if it is equal to ‘+’, ‘*’, etc, and, accordingly, compute the result. (If you want to be able to handle more than 2 operators, it is best to use a switch statement.) Sample runs: ----jGRASP exec: java Lab13d Calculate: 9.3 + 44.7 = 54.0 ----jGRASP exec: java Lab13d Calculate: 55 * 83 = 4565.0 e. Input data into an array The technique described in Parts C is also useful for processing data organized in columns and inputting that into an array. Go back to the code for PartC (NOT Part D) and modify the code so that it inputs 8 words into an array of 8 Strings. (Be sure to replace the variables word1, word2 etc by an array word[0], word[1], etc. and use a for-loop to get the input. The words should then be printed backwards. Tab delimited data: Sometimes the input tokens can contain spaces. For example, the “words” could be country names: India United States France China Germany Greece South Korea Brazil These are still just 8 countries! In such situations, a tab can be used as a delimiter, so the String would be stored as: "India\tUnited States\tFrance\tChina\tGermany\tGreece\tSouth Korea\tBrazil" In order for your Scanner to use a delimiter other than whitespace, you need to specify this before doing any input: scanLine.useDelimiter("\t"); Sample run: ----jGRASP exec: java Lab13d Enter 8 country names, all in one line, separated by tabs: India France Japan India Greece United States South Korea Mali Mali South Korea United States Greece India Japan France India Note: these are tab characters Villanova University CSC 1051 www.csc.villanova.edu/~map/1051 Dr. Papalaskari f. Processing data from text files, organized in columns (Combine Parts b & e) The technique described in (e) is useful for processing text files containing data organized in columns. We now modify FileInput.java from (b) , above, so that after it inputs each line, it uses the technique of Lab13e.java, above (i.e., a second Scanner) to “scan” 8 words from each line in the file and store these words in an array, then print the contents of the array backwards. Try this with the following file: http://www.csc.villanova.edu/~map/1051/s16/examples/eightwords.txt Sample output: Line: India France Japan United Arab Emirates Greece United States South Korea Mali Mali South Korea United States Greece United Arab Emirates Japan France India Line: apple orange asian pear fig persimmon grape raspbery pineapple pineapple raspbery grape persimmon fig asian pear orange apple Line: black white gray light gray dark gray red blue green green blue red dark gray light gray gray white black g. (Optional) Input directly from a website Would you like your program to access a website directly? Here is how. You need to 1) Add another import directive at the beginning or your program: import java.net.URL; 2) Set up your Scanner to read from the url instead of a file. Here is an example: String myurl = "http://www.csc.villanova.edu/~map/1051/s16/examples/oneHundredInts.txt"; InputStream inStream = new URL(myurl).openStream(); Scanner webScan = new Scanner (inStream); 3) Now you can use webScan as any other Scanner object, to input from a webpage as if it were any other text file. Try it with your program lab13a.java. This technique will work with most webpages, as long as they can be read as text (including html files). Villanova University CSC 1051 www.csc.villanova.edu/~map/1051 Dr. Papalaskari Lab 13 Comments Name:________________________ Comments on this lab, please: What was the most valuable thing you learned in this lab? What did you like best about this lab? Was there any particular problem? Do you have any suggestions for improving this lab as an effective learning experience?