Printing twice, not prompted for Scanner input - java

Iam working on some homework and an having an issue where once the user chooses an input to enter a sentence and the program writes "Please enter a sentence" it writes this twice when it should be once. Here is my code.
import java.util.Scanner;
public class ParseSentence{
public static void main(String []args){
Scanner sc = new Scanner(System.in);
int selection = -1;
String sentence = "";
boolean flag = true;
while(flag){
while(selection == -1){
System.out.print("Menu: \n 1. Enter a new sentence\n 2. Display the sentence in uppercase \n 3. count the number of words \n 4. count the number of vowels \n 5. Display the longest word in the sentence \n 0. Exit \n");
selection = sc.nextInt();
if(selection > 1){
if(sentence.equals("")){
System.out.println("Error please first enter a sentence");
selection =-1;
}
}
}
while(selection == 1){
System.out.println("Please enter a sentence");
sentence = sc.nextLine();
if(sentence.equals("")){
selection = 1;
}else
selection = -1;
}
if(selection == 2){
System.out.println(Upper(sentence));
selection = -1;
}
if(selection == 0)
break;
selection = -1;
}
}
public static String Upper(String s){
String morph = s.toUpperCase();
return morph;
}
}
The output looks like this
Menu:
1. Enter a new sentence
2. Display the sentence in uppercase
3. count the number of words
4. count the number of vowels
5. Display the longest word in the sentence
0. Exit
1
Please enter a sentence
Please enter a sentence
I tried to replicate the bug in another program to see if I am doing something wrong with while loop but I am stumped. thanks for help.

After the last sc.nextInt(), on the line where you entered 1 the terminating newline character is not yet read.
It will be read in the first iteration of your while loop.
That is, sentence = sc.nextLine() will be empty at first,
and the loop body will be executed one more time.
One simple solution is to add a sc.nextLine() right before the loop.
// read terminating newline that remained after last int input
sc.nextLine();
while (selection == 1) {
System.out.println("Please enter a sentence");
sentence = sc.nextLine();
if (sentence.equals("")) {
selection = 1;
} else {
selection = -1;
}
}

Related

How do I prevent an error message from repeating in Java?

I'm trying to write a program to calculate factorial but I can't figure out why the Error message displays twice if I enter a letter instead of an integer.
I feel like the issue has to do with Line 29 c = sc.next().charAt(0);, but am not sure how to fix it. Any help is appreciated.
My program:
public class Factorials {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
char c = 'Y';
int num = 0;
do
{
System.out.print("Enter a number to calculate its factorial: ");
while (!sc.hasNextInt()) {
System.out.println("Invalid Entry - Enter only Integers! Try Again: ");
sc.nextLine();
}
int result = 1;
num = sc.nextInt();
for(int i = 1; i <= num; i++) {
result = result * i;
}
System.out.println("The factorial of " + num + " is: " + result);
System.out.println("Do you wish to continue? Y/N: ");
c = sc.next().charAt(0);
}while(c == 'y' || c == 'Y');
sc.close();
}
}
Simple fix: Change the sc.nextLine(); in your code to a sc.next() and you should be good to go. This error occurs because .nextLine() considers the enter/return key as a separate character, while .next() doesn't. (The enter key when you press it after entering either 'y' or 'n': if you try it, the error message doesn't print twice if you enter a letter the first time you run the program).
Side note: You probably want it to be a .print(/*invalid input sentence*/) instead of a .println() to go along with how you take in your other number values.
Otherwise, you're good!
Finds and returns the next complete token from this scanner.
A complete token is preceded and followed by input that matches
the delimiter pattern
As jdk doc shows, the 'sc.next' method will return when it reaches space, enter or return. So when you enter 'y' with enter, the enter character is still in buffer. You can assign sc.nextLine to a variable, like
String str = sc.nextLine();
System.out.println(str);
You can see the enter character and your input character.
Both #TheSj and #Lahiru Danushka answer could solve this problem.
add sc.nextLine(); after c = sc.next().charAt(0);

Replacing a String statment that's being used by a constructor

So I'm working on a project to count the number of vowels and consonants of a desired string. I've got almost everything working, but I can't seem to get the option to replace the string with a new one to work properly. I think it's a problem with having the new choice be applied to the Driver construct but I can't seem to figure out a way to do that without breaking the program.
import java.util.*;
public class Driver{
private String entry;
int vowels = 0;
int cons = 0;
public Driver(String input){
entry = input;
this.count();
}
public boolean isVowel(char x){
return (x == 'A' || x == 'E' || x == 'I' || x == 'O' || x == 'U' ||
x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u');
}
public boolean isConsonant(char x){
return (((x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z')) && !isVowel(x));}
public int getVowels(){
return vowels;
}
public int getConsonants(){
return cons;
}
public void count(){
int l = entry.length();
for(int i = 0; i < l; i++){
if(this.isVowel(entry.charAt(i))){
vowels++;
}else{
if(this.isConsonant(entry.charAt(i))){
cons++;
}
}
}
}
static Scanner kb = new Scanner(System.in);
public static void main(String[] args){
int choice; //Choice from menu
int vowels = 0; //# of vowels in entry
int cons = 0; //# of consonants in entry
String entry; //User's input
System.out.print("Enter a string:");
entry = kb.nextLine();
do{
Driver sentence = new Driver(entry);
System.out.println("Enter a number");
System.out.println("1. Count the number of vowels in the string");
System.out.println("2. Count the number of consonants in the string");
System.out.println("3. Count both the vowels and consonants in the string");
System.out.println("4. Enter another string");
System.out.println("5. Exit the program:");
choice = kb.nextInt();
switch(choice){
case 1:
System.out.println("Vowels: " + sentence.getVowels());
break;
case 2:
System.out.println("Consonants: " + sentence.getConsonants());
break;
case 3:;
System.out.println("Vowels: " + sentence.getVowels() + "\nConsonants: " + sentence.getConsonants());
break;
case 4:
System.out.print("Enter a string:");
entry = kb.nextLine();
//Driver sentence = new Driver(entry);
break;
default:
System.out.println("Please enter a value input: ");
}
}while(choice != 5);
}
}
You should have the Driver Class on its own (without the main() method).
Then create another Class that will be your startup Class which will contain the main() method). For the sake of argument let's call it VowelsAndConsonants.
The problem that's causing all the grief is your keyboard entry of 1 to 5 for the Console menu. You are using the Scanner.nextInt() method which is okay as long as you know that the whatever is entered is not all consumed and remains within the Scanner buffer and this is because the Scanner.nextInt() method doesn’t read and consume the line separator that is applied when the Enter Key is hit. So, when Scanner.nextLine() is used as the next Scanner method the first thing it gets hold of is that line separator that's held within the Scanner buffer which in turn is just like hitting the Enter key and therefore it skips what was typed. On the other hand the Scanner.nextLine() method does read in and consume the line separator. One way to get around this problem is to add (in your case) kb.nextLine(); directly after the choice = kb.nextInt(); code line. This forces the line separator to be consumed and empties the buffer. In essence the menu would then look something like this:
Driver sentence = new Driver(entry);
do {
System.out.println("Enter a Menu choice (1 to 5): ");
System.out.println("1. Count the number of vowels in the string");
System.out.println("2. Count the number of consonants in the string");
System.out.println("3. Count both the vowels and consonants in the string");
System.out.println("4. Enter another string");
System.out.println("5. Exit the program:");
choice = kb.nextInt();
kb.nextLine(); // Consume
..... the rest of your do/while code .....
}
EDIT: Based on your Question in Comment: "I'm curious as to why
there is a difference in how the line separator is dealt with tho. Is
this just something that is in Java, or is there a reason that it
isn't consumed from nextInt()?"
The Scanner Class is quite involved. It is by design that the nextInt() does this since Scanner can work based on tokens. You can use nextInt() to accept multiple numbers on a single input using (for example) a whitespace delimiter and then with the Scanner.hasNextInt() or Scanner.hasNext() methods in conjuction with the Scanner.nextInt() you can individually acquire each value, for example:
Scanner kb = new Scanner(System.in).useDelimiter(" *");
System.out.println("Enter numbers delimited with a white-space: ");
while (kb.hasNextInt()) {
int x = kb.nextInt();
System.out.println(x);
}
If you were to run this code and at the prompt enter on one line:
2 4 6 8 10
(note the whitespace between numbers) you will see a display within the Console window of:
2
4
6
8
10
Through each iteration of the while loop x would equal the next integer token from the line of numbers entered. This sort of thing however is best suited for reading numbers from a text file which Scanner can do as well. Read up on the Scanner Class.

How can I verify the int length of scanner input?

I was able to get the program to run and work with error checking to make sure that the user input is in fact an int. The issue I ran into is that I only want it to be a 3-digit int. I'm having trouble getting that into the right place:
import java.util.*;
public class listMnemonics
{
public static void main(String[] args)
{
//Defines the "keypad" similar to that of a phone
char[][] letters =
{{'0'},{'1'},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'},
{'M','N','O'},{'P','Q','R','S'},{'T','U','V'},{'W','X','Y','Z'}};
//Creates the Scanner
Scanner scan = new Scanner(System.in);
Right here is where I need to implement that and I am running into the issue. I'm sure it's maybe only a line out of place or missing that I need, I just don't know what or where. As it sits, it will constantly ask me to enter a 3-digit number, no matter the length. Error checking for a string entered does currently work:
//Gives instructions to the user to enter 3-digit number
//Any amount of numbers will work, but instructions help
//System.out.println("Please enter a 3-digit number: ");
int j;
do
{
System.out.println("Please enter a 3-digit number: ");
while (!scan.hasNextInt()) {
System.out.println("That's not a 3-digit number! Try again!");
scan.next(); // this is important!
}
j = scan.nextInt();
}
//while (j <= 0); This works while not checking digit length
while (j != 3);
int w = (int) Math.log10(j) +1; //Found this, but not sure if it helps or not
String n = Integer.toString(w);
And here is the rest that get's it to do what I need it to:
//Determines char length based on user input
char[][] sel = new char[n.length()][];
for (int i = 0; i < n.length(); i++)
{
//Grabs the characters at their given position
int digit = Integer.parseInt("" +n.charAt(i));
sel[i] = letters[digit];
}
mnemonics(sel, 0, "");
}
public static void mnemonics(char[][] symbols, int n, String s)
{
if (n == symbols.length)
{
System.out.println(s);
return;
}
for (int i = 0; i < symbols[n].length; i ++)
{
mnemonics(symbols, n+1, s + symbols[n][i]);
}
}
}
Here's the output:
----jGRASP exec: java listMnemonics
Please enter a 3-digit number:
2345
Please enter a 3-digit number:
12
Please enter a 3-digit number:
123
Please enter a 3-digit number:
motu
That's not a 3-digit number! Try again!
With the help of MvG and pingul, this is what is currently working the way I was hoping:
import java.util.*;
import java.util.regex.Pattern;
public class listMnemonics
{
public static void main(String[] args)
{
// Defines the "keypad" similar to that of a phone
char[][] letters =
{{'0'},{'1'},{'A','B','C'},{'D','E','F'},{'G','H','I'},{'J','K','L'},
{'M','N','O'},{'P','Q','R','S'},{'T','U','V'},{'W','X','Y','Z'}};
// Creates the Scanner
Scanner scan = new Scanner(System.in);
// Gives instructions to the user to enter 3-digit number
// This 'Pattern' also guarantees that only 3 digits works.
Pattern threeDigitNumber = Pattern.compile("[0-9]{3}");
int j;
do
{
System.out.println("Please enter a 3-digit phone number: ");
// If it's not a 3-digit int, try again
while (!scan.hasNext(threeDigitNumber))
{
System.out.println("That's not a 3-digit number! Try again!");
// This is important!
scan.next();
}
j = scan.nextInt();
}
while (j <= 0);
String n = Integer.toString(j);
// Determines char length based on user input
char[][] sel = new char[n.length()][];
for (int i = 0; i < n.length(); i++)
{
// Grabs the characters at their given position
int digit = Integer.parseInt("" +n.charAt(i));
sel[i] = letters[digit];
}
mnemonics(sel, 0, "");
}
// Here is where the magic happens and creates the possible
// letter combinations based on the user input and characters
// selected in previous steps.
public static void mnemonics(char[][] symbols, int n, String s)
{
if (n == symbols.length)
{
System.out.println(s);
return;
}
for (int i = 0; i < symbols[n].length; i ++)
{
mnemonics(symbols, n+1, s + symbols[n][i]);
}
}
}
Condensed and reformatted your code reads
Scanner scan = new Scanner(System.in);
int j;
do {
System.out.println("Please enter a 3-digit number: ");
while (!scan.hasNextInt()) {
System.out.println("That's not a 3-digit number! Try again!");
scan.next(); // this is important!
}
j = scan.nextInt();
} while (j != 3);
Comparing that to the Scanner documentation we can see that the scan.next() call will read (and discard) the non-int token. Otherwise j will be the integer you read. And you continue doing so while the number you read is different from 3. Not the length of the number, but the number itself. So if you want to end the loop, enter 3. If you want to do so while following the prompt, enter 003.
If that's not what you want to check, then change the end of loop condition. Or perhaps change the way you test for three-digit numbers, by using regular expressions to match these.
Scanner scan = new Scanner(System.in);
Pattern threeDigitNumber = Pattern.compile("\\d\\d\\d");
int j;
System.out.println("Please enter a 3-digit number: ");
while (!scan.hasNext(threeDigitNumber)) {
if (scan.hasNext()) {
System.out.println(scan.next() + " is not a 3-digit number! Try again!");
} else {
System.out.println("Input terminated unepxectedly");
System.exit(1);
}
}
j = scan.nextInt();
As comments correctly indicate, the pattern "\\d\\d\\d" could just as well be written as "[0-9]{3}", or as "\\d{3}" or "[0-9][0-9][0-9]". Using {…} might be useful in situations where the number of digits is a variable.
The documentation for Scanner.hasNext(Pattern) requires the pattern to match the input. This apparently follows the Matcher.matches() semantics of matching the whole string against the pattern, as opposed to Matcher.find() which checks whether the string contains any part matching the pattern. So the input does not have to be enclosed in ^ and $, as I assumed at first, and in fact should not be using these unless the pattern is compiled with the Pattern.MULTILINE flag.
You may want to call Scanner.useDelimiter to delimit using line breaks only.
Scanner.useDelimiter("[\\r\\n]+")

java characters in a string

so my problem is that I need to get the user to enter a string. then they will enter a character that they want counted. So the program is supposed to count how many times the character they entered will appear in the string, this is my issue. If someone can give me some information as to how to do this, it'll be greatly appreciated.
import java.util.Scanner;
public class LetterCounter {
public static void main(String[] args) {
Scanner keyboard= new Scanner(System.in);
System.out.println("please enter a word");//get the word from the user
String word= keyboard.nextLine();
System.out.println("Enter a character");//Ask the user to enter the character they wan counted in the string
String character= keyboard.nextLine();
}
}
Here is a solution taken from this previously asked question and edited to better fit your situation.
Either have the user enter a char, or take the first character from
the string they entered using character.chatAt(0).
Use word.length to figure out how long the string is
Create a for loop and use word.charAt() to count how many times your character appears.
System.out.println("please enter a word");//get the word from the user
String word= keyboard.nextLine();
System.out.println("Enter a character");//Ask the user to enter the character they want counted in the string
String character = keyboard.nextLine();
char myChar = character.charAt(0);
int charCount = 0;
for (int i = 1; i < word.length();i++)
{
if (word.charAt(i) == myChar)
{
charCount++;
}
}
System.out.printf("It appears %d times",charCount);
This should do it. What it does is that it gets a string to look at, gets a character to look at, iterates through the string looking for matches, counts the number of matches, and then returns the information. There are more elegant ways to do this (for example, using a regex matcher would also work).
#SuppressWarnings("resource") Scanner scanner = new Scanner(System.in);
System.out.print("Enter a string:\t");
String word = scanner.nextLine();
System.out.print("Enter a character:\t");
String character = scanner.nextLine();
char charVar = 0;
if (character.length() > 1) {
System.err.println("Please input only one character.");
} else {
charVar = character.charAt(0);
}
int count = 0;
for (char x : word.toCharArray()) {
if (x == charVar) {
count++;
}
}
System.out.println("Character " + charVar + " appears " + count + (count == 1 ? " time" : " times"));

Write a program that prompts the user to input a sequence of characters and outputs the numbers of vowels

import java.util.*;
public class VowelCounter
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Input a series of characters: ");
String letters = keyboard.next();
int count = 0;
for (int i = 0; i < letters.length(); i++)
{
char characters = letters.charAt(i);
if (isVowel(characters) == true)
{
count++;
}
}
System.out.println("The number of vowels is: " + count);
}
public static boolean isVowel(char characters)
{
boolean result;
if(characters=='a' || characters=='e' || characters=='i' || characters=='o' || characters=='u')
result = true;
else
result = false;
return result;
}
}
The code works but im suppose to input "Spring break only comes once a year." which if i do with the spaces my program will only find the vowels of Spring. how do i make it so it will skip the spaces and read the whole sentence.
This is your problem:
String letters = keyboard.next();
It has nothing to do with the vowel-counting part - but everything to do with reading the value. The Scanner.next() method will only read to the end of the token - which means it stops on whitespace, by default.
Change that to
String letters = keyboard.nextLine();
and you should be fine.
You should verify this is the problem by printing out the string you're working with, e.g.
System.out.println("Counting vowels in: " + letters);
When you do:
String letters = keyboard.next();
The Scanner stops reading at the first whitespace.
To read the complete phrase until you press enter, you should use nextLine() instead:
String letters = keyboard.nextLine();
Just use
String letters = keyboard.nextLine();
instead of
String letters = keyboard.next();
This is because .nextLine() will read line by line so that you can have your complete statement in latters. Hope this will help you

Categories

Resources