How do you test that a string str is the empty string?
Below is the code I tried, but when I just hit enter on eclipse console, it does not print right output which should be "String is Null"
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
out.print("Press Y to continue: ");
String yes= in.next();
int LengthOfInput = yes.length();
if (LengthOfInput==0)
{
out.print("String is Null");
}
else {
out.print("String not null");
}
}
}
Your method correctly identifies whether a string is empty. Other than this method, you can also call isEmpty on a string or check of the string is equal to ""
if (string.isEmpty())
if (string.equals(""))
The reason why your code did not work as expected is because you read the user input wrongly. next method by default will not return an empty string because it will always try to find something to read.
To achieve your intended behaviour call nextLine instead of next.
Related
This question already has answers here:
How can I check if an input is a integer or String, etc.. in JAVA?
(8 answers)
Closed 5 years ago.
I've been given an exercise to ask a user for their name using a method. If the user doesn't input any text they should be asked again. I've got it working but if the user inputs a number it still prints out. How can I stop the user from being able to input a number?
Here's my code below
public static void main(String[] args) {
// call method
System.out.println("Hello " + getName());
}
public static String getName() {
// input a scanner
Scanner scanner = new Scanner(System.in);
// declare vars
String userName = "";
// while loop
while (userName.equals("")) {
// ask user for input
System.out.println("What is your name?");
userName = scanner.nextLine();
}
scanner.close();
return userName;
}
}
The best way to use regular expression.
String namePattern = "[^\\p{P}|^\\d+]+";
//true if name contains only alphabets, false - otherwise
boolean result = userName.matches(namePattern);
As regex is generally slow, a non-regex solution would be:
boolean containsDigit(final String string) {
boolean result = false;
if (string == null || string.isEmpty()) {
return result;
}
char[] characters = string.toCharArray();
for (char character : characters) {
if (Character.isDigit(character)) {
result = true;
break;
}
}
return result;
}
This will result in the following while-loop
while (userName.equals("") || containsDigit(userName)) {
...
}
Note: a cleaner alternative would be to use username.isEmpty() instead of username.equals("")
If you're able to, you could also use a 3rd party lib like ApacheCommons, and use their StringUtils.isAlpha() method.
The isAlpha() method also checks to see if the string provided is null or empty.
Well Scanner has several methods to treat the user input. One of the methods that you can use to check if the user input is an int is hasNextInt():
Returns true if the next token in this scanner's input can be interpreted as an int value in the specified radix using the nextInt() method.
So your code will be :
if(!scanner.hasNextInt()){
userName = scanner.nextLine();
}
Another approach is to use hasNext(Pattern) method with a pattern that matches only alphabetic strings.
package chapter6;
import java.util.Scanner;
public class formal_greeting {
public static void main(String[] args) {
String title;
String name;
String mr = null;
String miss = null;
String ms = null;
String mrs = null;
Scanner input = new Scanner(System.in);
System.out.print("Enter your name: ");
name = input.next();
System.out.print("Enter your title: ");
title = input.next();
if (title.equalsIgnoreCase(mr)) {
System.out.println("Hello sir");
}else if (title.equalsIgnoreCase(miss)) {
System.out.println("Hello ma'am");
}else if (title.equalsIgnoreCase(ms)) {
System.out.println("Hello ma'am");
}else if (title.equalsIgnoreCase(mrs)) {
System.out.println("Hello ma'am");
}else {
System.out.println("Hello " + name);
}
}
}
I can't figure out why my if statements won't work. so far it only displays (Hello "name") can someone please tell me what is wrong with my if statement???
Problem is not in the if statements.Change your method input.next() to input.nextLine() .Because using next() you will get only what you entered before the space. But if you use nextLine() the Scanner will read the entire input line.For more reference click here.
Hope this helps
You need to know the difference between a String variable and a string literal.
In your code, mr is a string variable. The value that it stores is null as you can see from this line:
String mr = null;
In the if statement, you test whether the user input is equal to the value string variable. Let's say you entered "Mr" in the console:
User input Value of the mr variable
"Mr" null
Are they the same? No.
The same goes for all the if statements. Finally the execution comes to the else and executes the stuff there since every if statement failed.
What you need to do is to use a string literal instead of a string variable.
A string literal is denoted by double quotes:
"This is a string literal"
So your if statements would look like:
if (title.equalsIgnoreCase("mr")) {
/* ⬆︎ ⬆︎
Quotes here!
*/
Alternatively, you can use variables as well. But you should not give them a value of null. Instead, give them a string literal:
String mr = "mr";
// etc.
This way, you don't need to change your if statement.
Write a method called hasComma that takes a name as an argument and that returns a boolean indicating whether it contains a comma. If it does, you can assume that it is in last name first format. You can use the indexOf String method to help you.
Write a method called convertName that takes a name as an argument. It should check whether it contains a comma by calling your hasComma method. If it does, it should just return the string. If not, then it should assume that the name is in first name first format, and it should return a new string that contains the name converted to last name comma first format. Uses charAt, length, substring, and indexOf methods.
In your main program, loop, asking the user for a name string. If the string is not blank, call convertName and print the results. The loop terminates when the string is blank.
However, my program doesn't return the converted name. If I type in a name like John Smith, the program just ends, rather than returning Smith, John.
public static void main(String[] args) {
String name;
Scanner reader = new Scanner (System.in);
System.out.println("Type a name, then press ENTER.");
name = reader.nextLine();
if (name == null) {
return;
} else {
convertName(name);
}
}
public static boolean hasComma(String name) {
return name.indexOf(',') >= 0;
}
public static String convertName(String name) {
if (hasComma(name)) {
return name;
} else {
int index = name.indexOf(' ');
String first = name.substring(0, index);
String last = name.substring(index + 1);
String convertedName = last + ", " + first;
return convertedName;
}
}
You are not printing the output of your method.
Instead of
convertName(name);
write
System.out.println(convertName(name));
This is a problem I've encountered several times, and always wondered why.
For my code below as an example, if a string of whitespace is entered, the method will not print. However, after the next input with a value string containing characters, it will print all the whitespace strings and the valid character containing string. Why is this delayed and stored in memory?
Example for the code below:
Enter " " returns nothing.
Enter " " returns nothing.
Enter "SwiggitySwooty" returns " " \n " " \n "SwiggitySwooty"
Explaination: The whitespace containing strings are delayed until a valid character string is entered.
Extra info: I use intellij, also happens when not sending the string to a method. I've also had this happen during a while(input.hasNext()) statement, in which I try to catch an invalid input as a string, when I want to take an integer. If I enter 'n' amount of legitimate integers, and then a string, it would print out my "please enter an integer" that 'n' amount of times like in this code.
Lastly, if anyone thinks of a better title for this, let me know so I can change it for more exposure for those with similar questions. Thank you.
Let me know if you guys need anything else!
/**
* Created by JacobHein on 4/19/15.
*/
import java.util.Scanner;
public class FizzString {
/*TODO
* Given a string str, if the string starts with "f" return "Fizz".
If the string ends
* with "b" return "Buzz". If both the "f" and "b" conditions are true, return
* "FizzBuzz". In all other cases, return the string unchanged. */
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
while(input.hasNext()) {
System.out.println(fizzString(input.nextLine()));
}
}
public static String fizzString(String str) {
String result=str;
int l=str.length();
if (str.charAt(0)=='f'||str.charAt(l-1)=='b') {
result="";
if (l>0) {
if (str.charAt(0)=='f') {
result="Fizz";
}
if (str.charAt(0)=='b') {
result="Buzz";
}
if (l>1) {
/*technique: continue the process if l>1 (within l>0 if statement),
prevents breaking the program.*/
if (str.charAt(l-1)=='b') {
result="Buzz";
}
if (str.charAt(0)=='f'&&str.charAt(l-1)=='b') {
result="FizzBuzz";
}
}/*end l>1*/
}/*end l>0*/
}/*end charAt if*/
return result;
}
}
I believe this is what you're looking for:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String inputLine = "";
do {
inputLine = input.nextLine();
System.out.println(fizzString(inputLine));
System.out.println("");
} while (inputLine.length() > 0);
System.out.println("Goodbye");
}
public static String fizzString(String str) {
// Given a string
// If both the "f" and "b" conditions are true, return FizzBuzz
if (str.startsWith("f") && str.endsWith("b")) {
return "FizzBuzz";
}
// If the string starts with "f" return "Fizz".
if (str.startsWith("f")) {
return "Fizz";
}
// If the string ends with "b" return "Buzz".
if (str.endsWith("b")) {
return "Buzz";
}
// In all other cases, return the string unchanged.
return str;
}
Results:
The problem is the behavior of the Scanner class:
The next and hasNext methods and their primitive-type companion methods
(such as nextInt and hasNextInt) first skip any input that matches the
delimiter pattern, and then attempt to return the next token. Both
hasNext and next methods may block waiting for further input. Whether a
hasNext method blocks has no connection to whether or not its
associated next method will block.
Internally, the Scanner class is performing the following operation:
while (!sourceClosed) {
if (hasTokenInBuffer())
return revertState(true);
readInput();
}
The method hasTokenInBuffer() skips all the delimiter tokens (by default is \p{javaWhitespace}+), so only when the class found a non-delimiter token, it returns true in the hasNext() method.
For example, if you type this content: "\n\n\n5\n" and then execute nextInt() method, you'll obtain a result of 5, because Scanner automatically skips all the return line characters.
If you want to find some string into a line, try with the method java.util.Scanner.findInLine instead of nextLine().
Use the patterns: ^f(.)* to look for every line that starts with a f character and the pattern (.)*b$ to look for every line that ends with a b character.
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.