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.
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.
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.
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 assignment I'm doing and it seems I can't get it to work properly.
The question is below.
A palindrome is a word or phrase that reads the same forward and
backward, ignoring blanks and considering uppercase and lowercase
versions of the same letter to be equal.for example,the following are
palindromes:
warts n straw
radar
able was I ere I saw Elba
xyzczyx
Write a program that will accept a sequence of characters terminated
by a period and will decide whether the string--without the
period---is a palindrome.You may assume that the input contains only
letters and blanks and is at most 80 characters long.Include a loop
that allows the user to check additional strings until she or he
requests that the program end.
Hint: Define a static method called isPalindrome that begins as
follows:
Precondition: The array a contains letters and blanks in
positions a[0] through a[used - 1]. Returns true if the string is a
palindrome and false otherwise.
public static boolean isPalindrome(char[] a, int used)
Your program should read the input characters into an array whose base
type is char and then call the preceding method. The int variable used
keeps track of how much of the array is used, as described in the
section entitled "Partially Filled Arrays."
This is my class code:
public class Palindrome_class
{
// instance variable
char[] characterArray;
//constructor
//#param data is a string of characters
public Palindrome_class(String data)
{
characterArray = data.toUpperCase().toCharArray();
}
//#return true if the word is a palindrome, otherwise returns false.
public boolean isPalindrome(char[] a, int used)
{
int i = 0, j = used - 1;
while (i < j)
{
if(characterArray[i] == characterArray[j])
{
i++;
j--;
}
else
{
return false;
}
}
return true;
}
}
This is my main code:
import java.util.Scanner;
public class palindromeTest
{
public static void main(String[] args)
{
int used = 0;
char[] chars = new char[80];
Scanner inputWord = new Scanner(System.in);
Scanner reply = new Scanner(System.in);
System.out.println("Enter a string characters, terminated by a period.");
String data;
String cq;
Palindrome_class word;
do
{
//input word from user.
data = inputWord.nextLine();
word = new Palindrome_class(data);
//check for palindrome.
if(word.isPalindrome(chars, used))
System.out.println(data + " is a palindrome.");
else
System.out.println(data + " is not a palindrome.");
//request to continue or quit.
System.out.println("Continue or Quit?");
cq = reply.nextLine();
}
while (cq.equalsIgnoreCase("continue"));
System.exit(0);
}
}
This is the results:
Enter a string characters, terminated by a period.
radar.
radar. is a palindrome.
Continue or Quit?
continue
use
use is a palindrome.
Continue or Quit?
continue
use.
use. is a palindrome.
Continue or Quit?
continue
apple.
apple. is a palindrome.
Continue or Quit?
Quit
Please tell me where I'm making a mistake.
You are checking whether a String is a palindrome with this call :
if(word.isPalindrome(chars, used))
However, used is 0, so your method always returns true.
You are also ignoring the instructions of your assignment. You are not doing anything with the chars array, you are not removing the period that's supposed to be at the end of the input String, your isPalindrome method is not static, etc...
U did a very little mistake.. U are sending "used" variable as 0 each time. ideally it should be length of a word.
please check it. use
used = data.length();
before sending it to the check 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.