Java: Two Scanners reading from the same input file. Doable? Useful? - java

I have to read in integers from an input file based on whether or not a string that appears before them is a certain keyword "load". There is no key number telling how many numbers are about to be inputted. These numbers must be saved to an array. In order to avoid creating and updating a new array for each additional number scanned, I'd like to use a second scanner to first find the amount of integers, and then have the first scanner scan that many times before reverting back to testing for strings. My code:
public static void main(String[] args) throws FileNotFoundException{
File fileName = new File("heapops.txt");
Scanner scanner = new Scanner(fileName);
Scanner loadScan = new Scanner(fileName);
String nextInput;
int i = 0, j = 0;
while(scanner.hasNextLine())
{
nextInput = scanner.next();
System.out.println(nextInput);
if(nextInput.equals("load"))
{
loadScan = scanner;
nextInput = loadScan.next();
while(isInteger(nextInput)){
i++;
nextInput = loadScan.next();
}
int heap[] = new int[i];
for(j = 0; j < i; j++){
nextInput = scanner.next();
System.out.println(nextInput);
heap[j] = Integer.parseInt(nextInput);
System.out.print(" " + heap[j]);
}
}
}
scanner.close();
}
My problem seems to be that scanning via loadscan, the secondary scanner only meant for integers, also moves the primary scanner forward. Is there any way to stop this from happening? Any way to make the compiler treat scanner and loadscan as separate objects despite them preforming the same task?

You may certainly have two Scanner objects read from the same File object simultaneously. Advancing one will not advance the other.
Example
Assume that the contents of myFile are 123 abc. The snippet below
File file = new File("myFile");
Scanner strFin = new Scanner(file);
Scanner numFin = new Scanner(file);
System.out.println(numFin.nextInt());
System.out.println(strFin.next());
... prints the following output...
123
123
However, I don't know why you would want to do that. It would be much simpler to use a single Scanner for your purposes. I called mine fin in the following snippet.
String next;
ArrayList<Integer> readIntegers = new ArrayList<>();
while (fin.hasNext()) {
next = fin.next();
while (next.equals("load") {
next = fin.next();
while (isInteger(next)) {
readIntegers.Add(Integer.parseInt(next));
next = fin.next();
}
}
}

Related

Output an array to the console from a .txt file

I am trying to copy the contents of a .txt file to an array and print it to the console.
The code requires a main method with two scanners (one to read input from the user, and the second to read the file), a method to make the array, and a method to print the array.
I have successfully managed to make an array and print it, but the output is not ideal. It is scattered and difficult to read. Can someone help me to improve my output so it reads more like a list?
Here is my code:
public class CutupSongCreator {
// Creates two Scanner objects; one reads input from console, the other scans a file
public static void main(String[] args) throws FileNotFoundException {
Scanner console = new Scanner(System.in); // SCANNER ONE (reads input)
System.out.print("What is the input filename? ");
String filename = console.next();
File f = new File(filename);
while (!f.exists()) {
System.out.print("That file does not exist. Try again: ");
filename = console.next();
f = new File(filename);
}
Scanner input = new Scanner(f); // SCANNER TWO (reads file)
SongLine[] arr = makeArray(input);
printArray(arr);
// Sort by genre
// System.out.print("What genre are you looking for: ");
// String genretype = console.next();
// if (genretype == input.next()) {
// System.out.print("You can't just make up a genre. Try again: ");
// genretype = console.next();
// }
// listLinesByGenre(arr, genretype);
}
// Creates an array of SongLines from a set of lines
public static SongLine[] makeArray(Scanner reader) {
int total = reader.nextInt(); // First int = # of lines
SongLine[] arr = new SongLine[total]; // New array to hold the length of the file
for(int i = 0;i < total; i++) {
String genre = reader.next();
int lineNumber = reader.nextInt();
String words = reader.nextLine();
SongLine temp = new SongLine(genre, lineNumber, words);
arr[i] = temp;
}
reader.close();
return arr;
}
// Prints out the elements of an array
public static void printArray(SongLine[] songs) {
System.out.println(Arrays.toString(songs));
}
}
My code makes use of a constructor class, which I could post if needed, but I think I just do not understand how to read or use the constructor file. Below are the current and desired output. The desired shows the genre, lineNumber, and script, and I would like to print it looking as so.
Current Output
Desired Output
Thank you.

How do I take a users input, add that to a new scanner, and then scan the input into an array?

I'm trying to create a program that takes the user's input and then scans the user's input into an array with a for loop. That way I can loop through the array to find if the string is a word palindrome or not. A word palindrome differs from a palindrome in that it is the whole word in reverse rather than each individual letter in reverse. When the program that I wrote prints it just prints null, which I believe means that it's not storing what the scanner scanned.
Below is what I've written:
String userInput, scannedWord;
Scanner keyboard = new Scanner(System.in); //scanner for user input
System.out.print("Please enter a sentence: ");
userInput = keyboard.nextLine(); //stores user input
Scanner stringScan = new Scanner(userInput); //scanner to scan through user input
int userInputLength = userInput.length(); //to find word count
int wordCount = 0; //for array size
for (int i = 0; i < userInputLength; i++) //finds word count
{
while(stringScan.hasNext())
{
scannedWord = stringScan.next();
wordCount = wordCount + 1;
}
}
String stringArray[] = new String[wordCount];
for (int i = 0; i < userInputLength; i++) //should store scanned words into the array
{
while (stringScan.hasNext())
{
scannedWord = stringScan.next();
stringArray[i] = scannedWord;
}
}
System.out.println(Arrays.toString(stringArray)); //how I've checked if it's storing
You've got some funky logic going on here. A few things:
userInput = keyboard.nextLine(); //stores user input
int userInputLength = userInput.length(); //to find word count
userInputLength is the length of the userInput string, which is the number of characters in the string, not the number of words.
It looks like the while loop is used simply to calculate the required size of the array, but the outer for loop is not required. You're effectively saying, for every character in the input string, while the scanner has another word, count the word, which doesn't make much sense.
You do something similar in your second for loop, which also doesn't make much sense.
for (int i = 0; i < userInputLength; i++) //finds word count
{
while(stringScan.hasNext())
{
scannedWord = stringScan.next();
wordCount = wordCount + 1;
}
}
It would be easier to use a List and save yourself the trouble that comes with fixed size arrays. You can just initialize the list and add things to it without caring about how big it is.
List<String> words = new ArrayList<String>();
words.add(word1);
words.add(word2);
Here's some code to simplify your problem a little:
Scanner keyboard = new Scanner(System.in); //scanner for user input
System.out.print("Please enter a sentence: ");
String userInput = keyboard.nextLine(); //stores user input
Scanner stringScan = new Scanner(userInput); //scanner to scan through user input
List<String> words = new ArrayList<String>();
while (stringScan.hasNext())
{
String scannedWord = stringScan.next();
words.add(scannedWord);
}
System.out.print(Arrays.toString(words.toArray())); // nasty! but you can see what's in the array for debugging

Adding .split into my code

I'm creating a console program in Java with an array, I need to enter all of my code on one line in the following format up to 100 times.
car_make_name : car_model_name : car_model_tax : car_model_price
It's two strings and two int variables, I have code written out but I don't know how to use .split to enter the correct information into the corresponding variable.
This is my code:
public class Main {
public static void main (String[] args)
{
//Arrays declared
String[] cars = new String[20];
String[] car_model_name = new String[20];
int[] car_model_tax = new int[20];
String[] car_make_name = new String[20];
int[] car_model_price = new int[20];
Scanner scan = new Scanner (System.in);
//Loop??
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.equals("quit", "QUIT", "Quit")) {
}
}
break;
for (int x = 0; x < cars.length; x++){
System.out.println("Enter details, separating each with a ':' ");
cars[x] = System.console().readLine();
}
}
}
First, you may prefer List but not array to store your information if you read input from console and you can't control the input length of your user.
Second, you may want to use String#split to split and convert it if necessary.
System.out.println("Enter details, separating each with a ':' ");
Scanner scan = new Scanner(System.in);
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.equals("quit")) {
break;
}
final String[] split = line.split(":");
// handle it
}
Third, A good book can improve your programming level so much.If you have no experience of programming, I recommend Head First Java. Otherwise, I recommend Thinking In Java.

Create java list from user input

I have a bit of a unique problem to solve and I'm stuck.
I need to design a program that does the following:
Inputs two series of numbers (integers) from the user.
Creates two lists based on each series.
The length of each list must be determined by the value of the first digit of each series.
The rest of the digits of each series of numbers becomes the contents of the list.
Where I'm getting stuck is in trying to isolate the first number of the series to use it to determine the length of the list.
I tried something here so let me know if this is what you're looking for. It would be better for you to provide your attempt first.
I also want to point out that Lists are for the most part dynamic. You don't have to worry about the size of them like a normal array.
Scanner sc = new Scanner(System.in);
ArrayList<Integer[]> addIt = new ArrayList<>();
boolean choice = false;
while(choice == false){
String line = sc.nextLine();
if(line.equalsIgnoreCase("n")){
break;
}
else{
String[] splitArr = line.split("\\s+");
Integer[] convertedArr = new Integer[splitArr.length];
for(int i = 0; i < convertedArr.length; i++){
convertedArr[i] = Integer.parseInt(splitArr[i]);
}
addIt.add(convertedArr);
}
}
This is assuming that you are separating each integer with a whitespace. If you are separating the numbers with something else just modify the split statement.
The user enters "n" to exit. With this little snippet of code, you store each array of Integer objects in a master ArrayList. Then you can do whatever you need to with the data. You can access the first element of each Integer object array to get the length. As you were confused how to isolate this value, the above snippet does that for you.
I would also advise you to add your parse statement in a try-catch block to provide error handling for invalid input that cannot be parsed to an integer.
This is one way of doing it with default arrays.
import java.util.Scanner;
public class ScanList {
public static void main(String[] args){
System.out.println("Array:");
Scanner s = new Scanner(System.in);
String line = s.nextLine();
String[] nums = line.split(",");
int[] result = new int[Integer.parseInt(nums[0])];
for(int i = 0; i<result.length;i++){
result[i]=Integer.parseInt(nums[i+1]);
}
for(int r:result){
System.out.println(r);
}
}
}
This is what I came up with:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Insert the first series of numbers: ");
String number1 = input.nextLine();
System.out.println("Insert the second series of numbers: ");
String number2 = input.nextLine();
String[] items = number1.split(" ");
String[] items2 = number2.split (" ");
List<String> itemList = new ArrayList<String>(Arrays.asList(items));
itemList.remove(0);
Collections.sort(itemList);
System.out.println(itemList);
} // End of main method

Line/Token based processing (java)

I'm writing a program to read data from files with various sports statistics. Each line has information about a particular game, in say, basketball. If a particular line contains an "#" symbol, it means that one of the teams is playing at home. I'm trying to count the lines that contain an "#" and output that to the user as the Number of Games in which either team played at home. The first file has that 9 games were played at home for some team, but my output keeps printing out 0 rather than 9. How can I fix this?
Here's the relevant code:
public static void numGamesWithHomeTeam(String fileName) throws IOException{
File statsFile = new File(fileName);
Scanner input1 = new Scanner(statsFile);
String line = input1.nextLine();
Scanner lineScan = new Scanner(line);
int count = 0;
while(input1.hasNextLine()){
if(line.contains("#")){
count++;
input1.nextLine();
} else{
input1.nextLine();
}
}
System.out.println("Number of games with a home team: " + count);
}
Your line variable always has the first line's value. You should set line in the loop, something like that.
while(input1.hasNextLine()){
if(line.contains("#")){
count++;
line = input1.nextLine();
} else{
line = input1.nextLine();
}
Edit: On the second look your code has other problem: the last line is never checked. You should not initialize line (set to null) and do the check after nextLine():
public static void numGamesWithHomeTeam(String fileName) throws IOException{
File statsFile = new File(fileName);
Scanner input1 = new Scanner(statsFile);
String line = null;
Scanner lineScan = new Scanner(line);
int count = 0;
while(input1.hasNextLine()){
line = input1.nextLine();
if(line.contains("#")){
count++;
}
}
System.out.println("Number of games with a home team: " + count);}

Categories

Resources