user3115997
user3115997

Reputation: 11

Scanner errors with array list

I am creating a program which takes a file name as a parameter and checks for palindromes in the text. The program will also replace letters based on a users input or remove a word based on the users input. For some reason, the scanner under

public void letter

and 

public void word

isn't working properly.

This is the error I am receiving after the program runs and the user types in:

What would you like to do? Here are your options: 

Press 1 to Print all palindromes 

Press 2 to Replace any letter  

Press 3 to remove all occurences of a word 

Press 4 to exit

2

What letter would you like to remove?

e

What letter would you like to add?

r

[ ]

What would you like to do? Here are your options: 

Press 1 to Print all palindromes 

Press 2 to Replace any letter  

Press 3 to remove all occurences of a word 

Press 4 to exit

This is the error which I get

Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1416)
at Homework6.main(Homework6.java:28)**

Code:

import java.util.ArrayList;
import java.util.Scanner;
import java.util.*;
import java.io.File;

public class Test {

static ArrayList<String> strings = new ArrayList<String>();

public static void main(String[] args) {
    Test test2 = new Test();
    try {
        Scanner scanner = new Scanner(new File(args[0]));
        while (scanner.hasNext()) {
            strings.add(scanner.next());
        }
    } catch (Exception e) {
    }

            //ArrayList<String> a = new ArrayList<String>(strings);
    while (true) {
        System.out.println("\nWhat would you like to do? Here are your options: \nPress 1 to Print all palindromes \nPress 2 to Replace any letter  \nPress 3 to remove all occurences of a word \nPress 4 to exit\n");
        Scanner s = new Scanner(System.in);
        String command = s.next();

        if (command.equals("1")) {
            test2.pal();
        } else if (command.equals("2")) {
            test2.letter();
        } else if (command.equals("3")) {
            test2.word();
        } else if (command.equals("4")) {
            System.exit(0);
        }
    }
}

public void pal() {
    int a;
    int c;
    // boolean isPalindrome() ;

    for (a = 0; a < strings.size(); a++) {
        String replace = strings.get(a);
        replace = replace.replaceAll("[.,']", "");
    }

    for (c = 0; c < strings.size(); c++) {
        boolean pal = PalindromeChecker.isPalindrome(strings.get(c));

        if (true) {
            System.out.print(strings.get(c));
        }
    }
}

public void letter() {

    int b;
    Scanner replaceLetter = new Scanner(System.in);
    System.out.println("What letter would you like to remove?");
    String badLetter = replaceLetter.next();
    System.out.println("What letter would you like to add?");
    String newLetter = replaceLetter.next();
    for (b = 0; b < strings.size(); b++) {
        String replaceVowels = strings.get(b);
        replaceVowels = replaceVowels.replace("badVowel", "newVowel");
    }
    replaceLetter.close();

    System.out.print(strings);
}

public void word() {

    Scanner removeWord = new Scanner(System.in);
    System.out.println("What word would you like to remove?");
    String word = removeWord.next();
    strings.remove(word);
    removeWord.close();
    System.out.print(strings);
}
}

Upvotes: 1

Views: 259

Answers (3)

Dennis Meng
Dennis Meng

Reputation: 5187

Expanding on @TheLostMind's answer, the problem is that when you call Scanner#close, it will also close the underlying stream if it implements the Closeable interface. Taken from the docs:

If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked. If this scanner is already closed then invoking this method will have no effect.

Thus, in your letter() and word() functions, when you call close, it will also close System.in. So, when you try to use a Scanner to read from System.in again, there's nothing left to read, and you get the NoSuchElementException.

Upvotes: 1

Reuben
Reuben

Reputation: 5736

Use

while(scanner.hasNextLine()){}

and scanner.nextLine

instead of hasNext() & next().

And if you are using java7 then it would be best to code like this:

try (Scanner scanner = new Scanner(new FileInputStream(file)) {

}

It will automatically close Scanner and is safe from any type of leak

Upvotes: 0

TheLostMind
TheLostMind

Reputation: 36304

Remove these lines .. it will work...

     replaceLetter.close ();
     removeWord.close();

Upvotes: 2

Related Questions