CSC1051 Data Structures and Algorithms I Dr. Papalaskari Lab 12 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 12 files. It is important to save all the data and program files for this lab in the same folder. Preparation: Lab 11 Review In part (e) of Lab 11 we explored how to input values from the user and store them in an array. Review your program Lab11e.java – recall that it uses Scanner to input integer values from the user. Save a copy of this program in your Lab 12 folder, renaming it as Lab12a.java A. Reading values from a file and storing them in an array 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/s15/examples/oneHundredInts.txt You would not want to re-‐type these numbers in order to enter them in your program interactively! In Java, you can direct the Scanner to input from a file, instead of from the keyboard. You do this by: 1) Replacing System.in by the file from which you are “reading” when you set up the Scanner object, i.e.: Scanner scan = new Scanner(new File("oneHundredInts.txt")); 2) In order to use the File class, above, you need to import some classes from java.io: import java.io.*; 3) You also need to add “throws IOException” to the heading of your main method, so it should read: public static void main(String[] args) throws IOException 4) Since you want to input 100 numbers, you need to enlarge the array to hold 100 integers. 5) Finally, you need to make sure that the file oneHundredInts.txt is saved in the same folder as your program and contains the correct data (a list of 100 numbers). • Some browsers add extra junk at the beginning and end of the file when saving files from the web—open the file in jGrasp and verify that your file consists of exactly those 100 numbers and nothing else CSC1051 Data Structures and Algorithms I Dr. Papalaskari B. Processing a text file, line by line www.csc.villanova.edu/~map/1051/s15/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/s15/examples/titanic.txt CSC1051 Data Structures and Algorithms I 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: Lab12c.java //******************************************************************** // Lab12c.java MA Papalaskari // Simple example: scanning from a String //******************************************************************** import java.util.Scanner; public class Lab12c { 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 : Lab12c.java – what does it do? ____________________________________________________________________ ____________________________________________________________________ D. Scanning from a String and doing something useful Next, we will create Lab12d.java by modifying Lab12c.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 Lab12c.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 CSC1051 Data Structures and Algorithms I 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 Lab12d Calculate: 9.3 + 44.7 = 54.0 ----jGRASP exec: java Lab12d 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 Lab12d 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 CSC1051 Data Structures and Algorithms I Dr. Papalaskari F. Processing data from text files, organized in columns (Combine Parts B & E) The technique described in Part E is useful for processing text files containing data organized in columns. We now modify FileInput.java from Part B, above, so that after it inputs each line, it uses the technique of Lab12e.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/s15/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/f14/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 lab12a.java. This technique will work with most webpages, as long as they can be read as text (including html files).