So I created some code to check if the first letter of the word that the user enters (stored in the variable word) is a consonant or vowel. If it is neither it outputs saying it is neither. However, I am using nextLine() instead of next() to get input. I understand that next() will not take input until they enter a valid character besides a space, and I know that nextLine() will go to the else statement if they enter just spaces. However, in nextLine when the user just puts enter and does not enter any character, no spaces, the program crashes. I tried checking if the string was equal to null and then making it print out "test" if it was proven true, however for some reason whenever I press enter I still get an error. Below is my code:
import java.util.Scanner;
public class WordStart {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.printf("Please enter a word: ");
String word = in.nextLine();
String lowerWord = word.toLowerCase();
String x = lowerWord.substring(0,1);
String test = null;
String empty = new String();
boolean vowel = x.equals("a")||x.equals("e")||x.equals("i")||
x.equals("o")||x.equals("u");
boolean conc = x.equals("b")||x.equals("c")||x.equals("d")||x.equals("f")||
x.equals("g")||x.equals("h")||x.equals("j")||x.equals("k")||
x.equals("l")||x.equals("m")||x.equals("n")||x.equals("p")||
x.equals("q")||x.equals("r")||x.equals("s")||x.equals("t")||
x.equals("v")||x.equals("w")||x.equals("x")||x.equals("y")||
x.equals("z");
if(vowel){
System.out.printf("%s starts with a vowel.\n", word);
}
else if(conc){
System.out.printf("%s starts with a consonant.\n", word);
}
else if(word.equals("")){
System.out.println("testEmpty");
}
else if(word.isEmpty()){
System.out.println("testNull");
}
else{
System.out.printf("%s starts with neither a vowel nor a consonant.\n", word);
}
}
}
Basically, I am trying to check if the user just pressed enter without entering anything and call them out on it. What method, line of code would help me do that. I tried using word.equals(null), but the IDE said that it was never true. Thanks in advance.
The error code I get when I just press enter is as follows
run:
Please enter a word:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.substring(String.java:1963)
at WordStart.main(WordStart.java:8)
C:\Users\Jordan\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 3 seconds)
I think the problem lies with this line:
String x = lowerWord.substring(0,1);
If the string is empty (nextLine will never return a null string) it is impossible to take a substring. You should probably check that the string is > 0 characters long.
if(x.length > 0)
String x = lowerWord.substring(0,1);
Firstly note that word.equals("") and word.isEmpty() checks the same condition. So there is no need to use them both. To check whether is String null use if (word == null). Checking the null and the emptyness of the String should be the first one you do.
Secondly in case you skip the input (get the empty String ""), you get IndexOutOfBoundsException, because lowerWord.substring(0,1); has no chance to find that index.
So:
if (word != null && !word.isEmpty()) {
// ...
}
Just check if it is null
if(variable==null)
should suffice
Related
EDIT: I figured it out! I got rid of the try-catch block because it just didn't work the way I wanted it to. The code below is my final one. Thank you to everyone who responded to this question.
I am trying to code a to-do list program. One function of this program is to search for the entries inside the string array. The user should only input a ONE WORD keyword so if the user inputs more than one word or none, a prompt should show telling the user to try again. The code I've written so far is inside a try-catch statement. Using next() scanner only takes the first word and disregards the rest when inputting a multiple-word keyword, instead of producing an Exception. Here is my code for it:
case 2:
String searchKeyword;
int success = 0;
while(success==0) {
System.out.print(">> Enter 1 keyword: ");
searchKeyword = sc.nextLine();
String splitSearchKeyword[] = searchKeyword.split(" ");
if (splitSearchKeyword.length == 1) {
if(Quinones_Exer2.searchToDoList(searchKeyword, todoList)==-1) {
System.out.println(">> No item found with that keyword!");
System.out.println();
}
else {
System.out.println(">> Found one item!");
System.out.println("("+(Quinones_Exer2.searchToDoList(searchKeyword, todoList)+1)+")"+" "+todoList[Quinones_Exer2.searchToDoList(searchKeyword, todoList)]);
System.out.println();
}
success++;
}
else {
System.out.println(">> Please input a single word keyword!");
System.out.println();
}
}
break;
}```
Use Scanner.nextLine() then split the supplied string. If the length of array is greater than 1 or the supplied string is empty then issue an invalid entry message and have the User enter the string over again:
while(tries2 == 0) {
searchKeyword = "";
while (searchKeyword.isEmpty()) {
System.out.println("Enter 1 keyword: ");
searchKeyword = sc.nextLine().trim();
if (searchKeyword.isEmpty() || searchKeyword.split("\\s+").length > 1) {
System.out.println("Invalid Entry! {" + searchKeyword
+ "You must supply a single Key Word!");
searchKeyword = "";
}
}
tries2++;
// ... The rest of your code ...
}
From the docs of Scanner.next():
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
You would need to call next() again to get the the rest of the input.
Much simpler would be to use Scanner.nextLine() to get entire line and then use String.split() with whatever delimiter you are using to get an array of all inputted keywords.
Edit: Scanner.next(pattern) may do what you are looking for. It throws InputMismatchException if the input does not match provided pattern(regex). Example:
scanner.next("^[a-zA-Z]+$")
This requires the entire line to consist of lower and/or upper case letters and nothing else.
i am trying to create a program for string anagram that follows these conditions:
method should allow only letters, white space, commas and dots in an anagram. If there are any other characters, then the string cannot contain an anagram.
The method should ignore all white space, commas and dots when it checks the text.
If there are no letters in the text, then the text cannot be an anagram.
import java.util.Arrays;
import java.util.Scanner;
public class StringAnagram {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter first string: ");
String first = in.nextLine().toUpperCase();
System.out.print("Enter second string: ");
String second = in.nextLine().toUpperCase();
String result = isAnagram(first, second);
System.out.println(result);
}
private static String isAnagram(String first, String second) {
String answer = "";
if (first.matches("[A-Z\\.\\,\\s]")) {
String st = first.replaceAll("\\.\\,\\s", "");
String nd = second.replaceAll("\\.\\,\\s", "");
char[] arraySt = st.toCharArray();
char[] arrayNd = nd.toCharArray();
Arrays.sort(arraySt);
Arrays.sort(arrayNd);
if(Arrays.equals(arraySt, arrayNd)) {
answer = "Anagram.";
}
else {
answer = "No anagram.";
}
}
else {
answer = "No anagram.";
}
return answer;
}
}
However when the program tests these 2 sentences, they are not anagram but they should be anagram. I have no idea where to look for mistake.
Eleven plus two is thirteen.
Twelve plus one is thirteen.
If you start your method as follows, it will fulfil validations mentioned in the 1st and the 3rd points of your question:
if (first == null || second == null || first.equals("") || second.equals("") || !first.matches("[A-Za-z,. ]+")
|| !second.matches("[A-Za-z,. ]+")) {
return "No anagram.";
}
The next thing you should do is to replace all white space, commas and dots with "" in order to ignore them:
String st = first.replaceAll("[,. ]+", "");
String nd = second.replaceAll("[,. ]+", "");
The complete code is as follows:
private static String isAnagram(String first, String second) {
if (first == null || second == null || first.equals("") || second.equals("") || !first.matches("[A-Za-z,. ]+")
|| !second.matches("[A-Za-z,. ]+")) {
return "No anagram.";
}
String answer = "";
String st = first.replaceAll("[,. ]+", "");
String nd = second.replaceAll("[,. ]+", "");
if (st.equals("") || nd.equals("")) {
return "No anagram.";
}
char[] arraySt = st.toCharArray();
char[] arrayNd = nd.toCharArray();
Arrays.sort(arraySt);
Arrays.sort(arrayNd);
if (Arrays.equals(arraySt, arrayNd)) {
answer = "Anagram.";
} else {
answer = "No anagram.";
}
return answer;
}
A test run:
Enter first string: london
Enter second string: britain
No anagram.
Another test run:
Enter first string: ram
Enter second string: mar
Anagram.
Another test run:
Enter first string: .
Enter second string: .
No anagram.
Another test run:
Enter first string: ,
Enter second string: .
No anagram.
Another test run:
Enter first string: ra.m
Enter second string: a.m.r
Anagram.
This: first.matches("[A-Z\\.\\,\\s]") tests if the first value is a single character that is either 1 capital letter, or a dot, or a comma, or any whitespace character.
Completely not what you want.
You can add System.out.println statements all over the place to print where your code is and the value of relevant variables. Follow the code along like you're the computer. There where what you think should happen does not match with what the sysout statements tell you – there is a bug there (there can be many, especially if you write this much stuff without testing anything first).
Better yet, use a debugger.
NB: Something as trivial as replacing one of your No anagram. strings with anything else just so you know which of the two got triggered would already have helped a lot.
NB: first.replaceAll("\\.\\,\\s", ""); is also broken; you've written way too much code here; test each individual moving piece. It's like a bike that doesn't do anything after you put it together: Take it apart piece by piece, test each piece individually.
This solution accepts strings from console input. That portion is omitted since that is working for you.
The idea is to selectively reduce the essence of what you are comparing to the bare minimum. Comments are provide to explain the logic. In the examples, all but the third one report as an anagram.
System.out.println(isAnagram("radar", "darar"));
System.out.println(isAnagram("ra.,. dar", "d.,a rar"));
System.out.println(isAnagram("r+a.,. dar", "d.,a + rar"));
System.out.println(isAnagram("Eleven plus two is thirteen.", "Twelve plus one is thirteen."));
// This method accepts mixed case strings. The conversion to upper case is
// done within the method.
public static String isAnagram(String first, String second) {
// get rid of allowed characters and convert to upper case
String st = first.replaceAll("[., ]","").toUpperCase();
String nd = second.replaceAll("[., ]","").toUpperCase();
// Now get rid of all alpha characters and compare to the empty string.
// Only if both are equal are the strings potential anagrams.
// Otherwise, the illegal characters would be present.
if (st.replaceAll("[A-Z]","").equals("") &&
nd.replaceAll("[A-Z]","").equals("")) {
// this is your original code
char[] arraySt = st.toCharArray();
char[] arrayNd = nd.toCharArray();
Arrays.sort(arraySt);
Arrays.sort(arrayNd);
// don't set a value just return it's an
// anagram
if (Arrays.equals(arraySt, arrayNd)) {
return "Anagram.";
}
}
// Otherwise, it's not
return "No Anagram.";
}
this is my first time asking a question. If I'm breaking any rules let me know please :)
I want to verify that the user only types in only one character and store in a variable I have already declared initially. As well, loop back the question for user to type in again if they did not do what they are asked for
Here is a what I have done so far
import java.util.Scanner;
public class arraytesting {
public static void main(String[] args) {
Scanner myKeyboard = new Scanner(System.in);
int user_Choice;
int rowAndcolumns;
char[][] user_Array;
char user_Char;
do {
System.out.print("Enter your choice (1 to 9): ");
user_Choice = myKeyboard.nextInt();
if (user_Choice < 1 || user_Choice > 9)
System.out.println("Illegal choice, please try again.");
} while (user_Choice < 1 || user_Choice > 9);
switch (user_Choice) {
case 1:
do {
System.out.print("\nHow many rows and columns (min 4 & max 20)? ");
rowAndcolumns = myKeyboard.nextInt();
if (rowAndcolumns < 1 || rowAndcolumns > 9)
System.out.println("Illegal choice, please try again.");
} while (rowAndcolumns < 4 || rowAndcolumns > 20);
do {
System.out.print("Which character do you want to fill your square with? (only one character)");
user_Char = myKeyboard.next().charAt(0);
if () // error message for user if they did not type correctly, Idk what to put in the
System.out.println("Illegal choice, please try again.");// boolean for it to compare
System.out.print(user_Char);
} while (); // using do-while loop to loop back question, if they don't type in correctly, i
// would only like for user to type in only one character
break;
}
}
}
I know I can put both of them in one do-while loop, but I want to focus on getting the boolean to check for user input.
edit: I would only like the user to enter only one single character
ex. '#' or 'a'
whereas "##" or "i am typing something that is not one character" is wrong
inside the spaces of if and while are how I want it to be verified
There is no need to do any check for "only 1 character entered". That makes no sense. You can't predict the future, so you cannot know if a user will enter more characters after 1 character has been entered. You will either just take the first character entered and work with it and ignore any potential additional characters - or you have to wait for more than 1 character, essentially breaking the program for users who do the right thing (enter only one character), just to be able to give them an error message when they finally do the wrong thing (enter another character).
That being said, this code:
user_Char = myKeyboard.next().charAt(0);
will actually wait for several characters to be entered until some kind of delimiter (per default some whitespace character, e.g. newline) is entered. That's exactly what you do not want.
You want to get one character from input, and one only. You don't have to care about more characters being entered after that:
user_Char = myKeyboard.next(".").charAt(0);
This tells myKeyboard to return the next String that matches the regex ".", which is any character, and only 1 character.
If you want to validate the entered character, e.g. only alphanumeric characters allowed, you can update your if and while to something like this:
if (!Pattern.matches("[a-zA-Z0-9]", new String(user_Char)))
or even better, use the String returned by myKeyboard.next("."):
String user_String = myKeyboard.next(".");
user_Char = user_String.charAt(0);
if (!Pattern.matches("[a-zA-Z0-9]", user_String))
or you could directly tell myKeyboard to only allow valid characters and skip the entire do/if/while error handling:
user_Char = myKeyboard.next("[a-zA-Z0-9]").charAt(0);
Edit
One thing your code doesn't handle right now is invalid inputs, e.g. letters when you call nextInt. This will actually throw a java.util.InputMismatchException, and you might want to wrap your nextInt() and next(...) calls in try-catch blocks to handle these exceptions.
Please check the code below, based on the discussion with Max, I used the .length() method to check the lenght of the string that the user typed.
You can check the type of the character to avoid the runtime exception in the first if statement using some methods in Character class that you use to check if the input is digit/letter or not ?
Character.isDigit(char)
Character.isLetter(char)
Character.isLetterOrDigit(char)
I also changed some variable names, Java is following the camel case style and class name has to be capitalized. I also refactored some code to check the range of the numbers to git rid of repeating same code on and on, check the method betweenExclusive
package stackoverflow.q2;
import java.util.Scanner;
public class Question2 {
public static void main(String[] args) {
Scanner myKeyboard = new Scanner(System.in);
int userChoice;
int rowAndcolumns;
char[][] user_Array;
char userChar;
do {
System.out.print("Enter your choice (1 to 9): ");
userChoice = myKeyboard.nextInt();
if ( !betweenExclusive(userChoice, 1,9) )
System.out.println("Illegal choice, please try again.");
} while (!betweenExclusive(userChoice, 1,9));
switch (userChoice) {
case 1:
do {
System.out.print("\nHow many rows and columns (min 4 & max 20)? ");
rowAndcolumns = myKeyboard.nextInt();
if (!betweenExclusive(rowAndcolumns ,1 , 9))
System.out.println("Illegal choice, please try again.");
} while (!betweenExclusive(rowAndcolumns ,4 , 20));
String input;
while (true){
System.out.print("Which character do you want to fill your square with? (only one character)");
input = myKeyboard.next();
// error message for user if they did not type correctly, Idk what to put in the
// boolean for it to compare
if ( input.length()>1){
System.out.print("Illegal character, try again please !!! ");
}else{
userChar = input.charAt(0);
System.out.print(userChar);
break;
}
} // using do-while loop to loop back question, if they don't type in correctly, i
// would only like for user to type in only one character
break;
}
}
public static boolean betweenExclusive(int x, int min, int max)
{
return x>=min && x<=max;
}
}
So, I posted this nearly identical code yesterday, asking about how to leave the punctuation at the end of a reversed sentence after using .split. I'm still struggling with it, but I'm also having another issue with the same code: And here is my screen shot http://i.stack.imgur.com/peiEA.png
import java.util.Scanner;
import java.util.StringTokenizer; // for splitting
public class MyTokenTester
{
public static void main(String\[\] args)
{
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String\[\] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
for (int count = words.length -1; count>=0; count--) // reverse the order and assign backward each token
{
backward += words\[count\] + " ";
}
System.out.println(backward); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
sentinel = sentinel.toLowerCase(); // regardless of case
} while (!sentinel.equals("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
} // end class MyTokenTester][1]][1]
As you guys can probably see my from screen shot, when the user is prompted to add another sentence in, the previous sentence is read back again.
My questions are:
How do I use charAt to identify a character at an undefined index (user input with varying lengths)
How do I stop my sentence from reading back after the user decides to continue.
Again, as I said, I'd posted this code yesterday, but the thread died and I had additional issues which weren't mentioned in the original post.
To address part 2, if you want to stop the sentence from reading back previous input, then reset backward to an empty string, because as it stands now, you're constantly adding new words to the variable. So to fix this, add this line of code right before the end of your do-while loop,
backward = "";
To address part 1, if you want to check the last character in a string, then first you have to know what is the last index of this string. Well, a string has indexes from 0 to str.length()-1. So if you want to access the very last character in the user input, simply access the last word in your words array (indexed from 0 to words.length - 1) by doing the following,
words[count].charAt(words[count].length() - 1);
Note that count is simply words.length - 1 so this can be changed to your liking.
1) So you have this array of strings words. Before adding each word to the backward string, you can use something like: words[count].chartAt(words[count].length() - 1). It will return you the charater at the last position of this word. Now you are able to do you checking to know wether it is a letter or any special char.
2) The problem is not that it is reading the previous line again, the problem is that the backward string still has the previous result. As you are using a + operator to set the values of the string, it will keep adding it together with the previous result. You should clean it before processing the other input to have the result that you want.
here is your code:
import java.util.*;
public class main{
public static void main(String[] args){
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String[] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
List<String> items = Arrays.asList(words);
Collections.reverse(items);
System.out.println(generateBackWardResult(items)); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
// i use quals ignore case, makes the code more readable
} while (!sentinel.equalsIgnoreCase("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
static String generateBackWardResult(List<String> input){
String result="";
for (String word:input){
result =result +" "+word;
}
return result;
}
} // end class MyTokenTester][1]][1]
there are also some thing to mention:
* never invent the wheel again! (for reverting an array there are lots of approaches in java util packages, use them.)
*write clean code, do each functionality, i a separate method. in your case you are doing the reverting and showing the result in a single method.
String validation issue:
This method works for the most part, but theres some apparent logic problem. If a user hits enter at the console with no input, it should return the "Error! this entry required" message, but it doesnt. I would have imagined it would, since I am testing for an input of
one or less chars
public String getChoiceString(String prompt, String s1, String s2) {
this.println(prompt);
String userChoice = this.sc.next();
String i;
boolean isValid = false;
while (isValid == false)
{
if (userChoice.equalsIgnoreCase(s1) || userChoice.equalsIgnoreCase(s2))
{
isValid = true;
}
else if (userChoice.length() <= 1 || userChoice.equalsIgnoreCase("")) {
System.out.println("Error! This entry is required. Try again.");
userChoice = this.sc.next();
}
else {
this.println("Error! Entry must be " + s1 + " or " + s2 + ". Try again.");
userChoice = this.sc.next();
}
}
return userChoice;
From here I create an instance of the class which contains this method. It is called console. I call the methods from this:
public class ConsoleTestApp {
public static void main(String[] args) {
System.out.println("Welcome to the Console Tester application");
System.out.println();
//get console object
Console console = IOFactory.getConsoleIO();
console.println("Int Test");
console.getIntWithinRange("Enter an integer between -100 and 100: ", -100, 100);
console.println();
console.println("Double Test");
console.getDoubleWithinRange("Enter any number between -100 and 100: ", -100, 100);
console.println();
console.println("Required String Test");
console.getRequiredString("Enter your email address: ");
console.println();
console.println("String Choice Test");
console.getChoiceString("Select one (x/y): ", "x", "y");
}
}
It doesn't seem like much of anything happens when you just enter a carriage return with Scanner#next. The Javadoc mandates that it only matches on a complete token with its delimiter.
The default delimiter for Scanner is \p{javaWhitespace}+. In essence, it describes a whole token as having at least one whitespace character in it.
Now, let's inspect the empty String. It doesn't contain any character in it. So, if we were going to match against the default delimiter regex, we would fail:
Scanner sc = new Scanner(System.in);
Pattern ptn = sc.delimiter();
System.out.println(ptn);
String empty = "";
String regex = "\\p{javaWhitespace}+";
System.out.println(empty.matches(regex)); // prints false
So, the pattern doesn't match, and the Scanner will block until it matches something, like A phrase.
So, instead of trying to deal with any headache that may be induced from next(), what you may be looking to use instead is nextLine(). In most cases, you want to use nextLine() when you want to match the entire line of entry, and next() when you're processing multiple elements in a single line.
String userChoice = this.sc.nextLine(); // wherever this Scanner instance lives...
This will match on anything containing a line separator, and since hitting return/enter will produce that, it will match the entire line you enter, even if it's a blank line.