Here is my code:
import java.util.Scanner;
public class BankAccount1
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
char pickup;
char size;
char type;
String name;
double cost=0.0;
int i;
for (i=0; i<2; i++)
{
System.out.println("What is your name?");
name = input.nextLine();
System.out.println("size of pizza: ");
size = input.next().charAt(0);
System.out.println("type of pizza: ");
type = input.next().charAt(0);
System.out.println("pick up or delivery?");
pickup = input.next().charAt(0);
if(size == 'S' || type == 'V') {cost = 10.0;}
else if(size == 'M' || type == 'V') {cost = 12.25;}
else if(size == 'L' || type == 'V') {cost = 14.50;}
else if(size == 'S' || type == 'C') {cost = 7.0;}
else if(size == 'M' || type == 'C') {cost = 8.0;}
else if(size == 'L' || type == 'C') {cost = 9.0;}
if(pickup == 'D'){
cost=cost+1.50;
System.out.println("Name: "+name+". Your cost is: "+cost);}
else {
System.out.println("Name: "+name+". Your cost is: "+cost);}
}
}
}
I have a for loop in my code, and it asks the name, size, type and pickup. The first time it is run, it asks all fields to be entered, but for the 2nd time, the name field does not let me input the name for some reason, it prints the "What is your name?" but it does not let me enter the name...? can someone tell me why?
Thanks.
this is what it looks like: http://i.stack.imgur.com/eb1BA.jpg
Due to the fact that
input.next()
does not consume newline characters, these get passed passed back to your loop and does not allow a value to be entered. You would need to add:
for (i = 0; i < 2; i++) {
// existing input.next() statements in here
...
input.nextLine();
}
at the end of the for loop to fix.
When you use a Scanner with System.in, data isn't read from System.in until a newline (you've hit Enter). So what you actually have in the Scanner's buffer is:
Jake\nL\nV\nD\n
The key here is that D doesn't get sent to the Scanner's buffer until you've pressed enter. That's why there's that \n at the end. Normally, when you're calling input.next(), that previous stray newline gets gobbled up. But when you call input.nextLine() the second/third time around the for loop, it's reading that stray trailing newline:
here ----v
Jake\nL\nV\nD\n
So you get a blank line, essentially reading everything between the D and \n, which is nothing.
You need to call nextLine() each time and call charAt(0) on the resulting String.
Replace your input.next()'s with input.nextLine()'s. That should fix it.
I had a similar problem, and this helped me.
declare this outside the loop:
boolean ranOnce=false;
then inside the loop declare this
if(!ranOnce){ranOnce=true;String s=input.nextLine();}
Related
I'm doing an assignment that converts a string sentence into pig latin.
I've planned and written all the code but I get this error:
String index is out of range
Below is my code:
import java.util.*;
public class project1d {
public static void main(String[] args){
System.out.println("This is a pig latin translator. Enter a sentence to convert.");
Scanner console = new Scanner(System.in);
pigLat(console);
}
public static void pigLat(Scanner console){
String sentence = console.next();
int start = 0;
int end = 0;
int counter =0;
while(sentence.length()>0){
while(end<sentence.length()-1){
while(sentence.charAt(counter+1)!=' '){
counter++;
end = counter;
}
String word = sentence.substring(start,end);
int index= 0;
char letter= word.charAt(index);
while (letter != 'a' || letter != 'e' || letter != 'i' ||
letter != 'o' || letter != 'u'){
index++;
}
System.out.print(word.substring(index,word.length()-1)+"-");
System.out.print(word.substring(0,index-1)+"ay");
counter++;
start=end+1;
}
System.out.println("Do you wanna put in another? Press ENTER to quit");
sentence = console.next();
}
}
}
I think the third while loop is increasing one too many times, but I can't figure out how to fix this or if that's even the problem.
The actual java errors are listed below:
- java.lang.StringIndexOutOfBoundsException: String index out of range: 4
- at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:47)
- at java.base/java.lang.String.charAt(String.java:693)
- at project1d.pigLat(project1d.java:15)
- at project1d.main(project1d.java:6)
Any help is appreciated.
Unfortunately, there are many things wrong with the code, aside of whether it does what it's intended to do or not.
You're increasing the indexes and checking the value without confirming whether those indexes are valid.
You are not clearing the variables before using them again after the first iteration of the whole thing.
You're increasing the index but you got an infinite loop at the letter check because you're not changing the letter when you increase the index.
The letter check is checking conditions that overlap - letter!= a || letter!=e will always be true, thus this makes it an infinite loop too.
As Andy pointed out: String sentence = console.next(); will only read a single word. Use nextLine instead.
Please try:
public static void pigLat(Scanner console){
String sentence = console.next();
int start = 0;
int end = 0;
int counter =0;
while(sentence.length()>0){
start = 0; end = 0; counter = 0;
while(end<sentence.length()-1){
while(sentence.length()>counter+1 && sentence.charAt(counter+1)!=' '){
counter++;
end = counter;
}
String word = sentence.substring(start,end);
if(word.length()>0){
int index = 0;
char letter = word.charAt(index);
while(index+1<word.lenght() && letter != 'a' && letter != 'e' && letter != 'i' && letter != 'o' && letter != 'u'){
index++;
letter = word.charAt(index);
}
System.out.print(word.substring(index,word.length()-1)+"-");
System.out.print(word.substring(0,index-1)+"ay");
}
counter++;
start=end+1;
}
System.out.println("Do you wanna put in another? Press ENTER to quit");
sentence = console.nextLine();
}
It's just natural that your code has some mistakes, as you're still learning how to do that properly. Keep it up ;)
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.
I'm trying to parse a char from console input using in.nextLine() and from there take charAt(0). My problem is after asking the user to enter a string to perform the in.nextLine() on, it skips the input and yields an error due to trying to get the first character of a null string.
System.out.print("Select an operator (+, -, *, /), 'c' or 'C' to clear, or 'q' to quit: ");
String temp = in.nextLine();
char tempOperator = temp.charAt(0);
the error is
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
full program is available here
General comments and suggestions always welcome.
Thanks in advance.
When you do cValue = in.nextDouble();, it reads the next token(full value) and parses it to double. If the return key was pressed at this time, \n is the next token in the buffer to read.
When you do: String temp = in.nextLine();, it reads the \n from the buffer of the previous enter and charAt(0) fails as it has read only empty("") string.
To overcome the issue, either skip the previous buffer by adding an addition in.nextLine(), add \n \r as skip pattern as below (this is the pattern defined in Scanner.class as LINE_SEPARATOR_PATTERN):
in.skip("\r\n|[\n\r\u2028\u2029\u0085]");
or put a small while loop as below:
String temp = "";
while((temp.length() < 0){
temp = in.nextLine();
}
One thing you might consider is instead of doing this:
String temp = in.nextLine();
Do this:
String temp = in.next();
That of course is assuming that you only want a single character from the user input, which it looks like that is all you are asking the user for. This will get rid of the exception you are receiving. However, you may want to read the whole line first to see what the length is, if you would like to throw an error when the user types more than one character.
Well, the problem is in the line in.nextDouble().
Scanner#nextDouble reads the next token from the user as double. So, when you pass a value 4.5 as input, then the nextDouble just reads the token 4.5 and skips the linefeed after that input that user have entered. Now this linefeed(Since this is a new line), will be regarded as input for the next Scanner.nextLine. And hence your in.nextLine after in.nextDouble is reading the newline left over by the previous in.nextDouble.
So, the workaround is the same that #tjg184 has pointed out in his answer. Add an empty in.nextLine after in.nextDouble that will read that newline left over. So, that your coming in.nextLine reads the input actually passed.
cValue = in.nextDouble();
in.nextLine(); // Add this before your `while` which will read your `newline`
while (true) {
//continue;
}
Whereas, Scanner.nextLine reads the complete input till the newline. So, it will not leave any newline to be read by the next read by user.
Although this answer was not needed, as the #tjg184's answer does the same. I just added it to give a better explanation of what exactly is happening.
Looking at your program, it's because of String temp = in.nextLine();. When the user hits the "Enter" key, it essentially is skipping this statement since the user typed hit "Enter". Try the following. Note, I only added the following line String enter = in.nextLine();
import java.util.Scanner;
public class Calculator
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
char operator = 'z'; //initialize operator
double cValue; //current value
double rhValue; //right hand value
boolean cont = true;
System.out.print("Enter starting value: ");
cValue = in.nextDouble();
// disregard the "Enter" key
String enter = in.nextLine();
while(true)
{
System.out.print("Select an operator (+, -, *, /), 'c' or 'C' to clear, or 'q' to quit: ");
String temp = in.nextLine();
char tempOperator = temp.charAt(0);
if (tempOperator == 'c' || tempOperator == 'C')
{
cValue = 0.0;
System.out.println("Current value is: " + cValue);
System.out.println();
}
else if(tempOperator == 'q')
{
System.out.println("Final result: " + cValue);
System.exit(1);
}
else if(tempOperator == '+' || tempOperator == '-' || tempOperator == '*' || tempOperator == '/')
{
operator = tempOperator;
break;
}
else
throw new IllegalArgumentException("operator not valid");
}
System.out.println("Enter a right hand value (type double): ");
rhValue = in.nextDouble();
System.out.println("Math expression: answer " + operator + "= " + rhValue);
switch(operator)
{
case '+': cValue =+ rhValue;
break;
case '-': cValue =- rhValue;
break;
case '*': cValue = cValue * rhValue;
break;
case '/': cValue = cValue / rhValue;
break;
}
System.out.println("Current value is: " + cValue);
}
}
import java.util.Scanner;
public class Power1Eng {
public static void main(String[] args) {
double x, prod = 1;
int n;
String s;
Scanner input = new Scanner(System.in);
System.out.print("This program prints x(x is a real number) raised to the power of n(n is an integer).\n");
outer_loop:
while (true) {
System.out.print("Input x and n: ");
x = input.nextDouble();
n = input.nextInt();
for (int i = 1; i <= n; i++) {
prod *= x;
}
System.out.printf("%.1f raised to the power of %d is %.4f. Do you want to continue?(Y/N) ", x, n, prod);
s = input.nextLine();
if (s.charAt(0) == 'Y')
continue;
else if (s.charAt(0) == 'N')
break;
else {
inner_loop:
while (true) {
System.out.print("Wrong input. Do you want to continue?(Y/N) ");
s = input.nextLine();
if (s.charAt(0) == 'Y')
continue outer_loop;
else if (s.charAt(0) == 'N')
break outer_loop;
else
continue inner_loop;
}
}
}
}
}
There was only trivial logical error when I used just next() method, but when I changed
next() method to nextLine() method, this error shows.
How can I fix this problem?
There are two problems. The first is that your string could be empty, and then fetching the first character will give an exception.
if (s.charAt(0) == 'Y') // This will throw if is empty.
Either test the length of the string to see if there is at least one character, or just use String.startsWith instead of charAt:
if (s.startsWith('Y'))
The second problem is that you entered a new line after your first input, and nextLine reads up to the next new line character only.
You could check for an initial character count, to make sure there are the correct number of characters that you expect. i.e:
while (true)
{
// ... some code ...
if (s.length() < 1)
{
continue;
}
// ... some code ...
}
This way, you wouldn't even have to continue running the rest of the code, which if the code base were larger, would help to optimize performance.
The "red text" that you see in the console is an indication of text being sent to standard error. In this case, it is an indication that your program has crashed.
The main problem you are encountering is with this logic:
System.out.print("Input x and n: ");
x = input.nextDouble();
n = input.nextInt();
for (int i = 1; i <= n; i++) {
prod *= x;
}
System.out.printf("%.1f raised to the power of %d is %.4f. Do you want to continue?(Y/N) ", x, n, prod);
s = input.nextLine();
Suppose the user input is:
2.1 4(enter)
input.nextDouble() will take 2.1, leaving 4(enter) on the standard input stream.
input.nextInt() will take 4, leaving (enter) on the standard input stream.
input.nextLine() will take "" (empty string), finally clearing the (enter) from the initial user input of x and n.
I have the program made up until the point where it has to ignore and punctuations and spaces in the thread and I was wondering if anyone could help me with the coding for that? What I've been trying out doesn't seem to be working. Here is what I have so far:
import java.util.Scanner;
public class PalindromeTester
{
public static void main (String[] args)
{
String str, another = "y";
int left, right;
char charLeft, charRight;
Scanner scan = new Scanner (System.in);
while (another.equalsIgnoreCase("y")) // allows y or Y
{
System.out.println ("Enter a potential palindrome: ");
str = scan.nextLine();
left = 0;
right = str.length() - 1;
while (left < right)
{
charLeft = str.charAt(left);
charRight = str.charAt(right);
if (charLeft == charRight)
{
left++;
right--;
}
else if (charLeft == ',' || charLeft == '.' ||
charLeft == '-' || charLeft == ':' ||
charLeft == ';' || charLeft == ' ')
left++;
else if (charRight == ',' || charRight == '.' ||
charRight == '-' || charRight == ':' ||
charRight == ';' || charRight == ' ')
right--;
else
break;
}
System.out.println();
if (left < right)
System.out.println ("That string is NOT a palindrome.");
else
System.out.println ("That string IS a palindrome.");
System.out.println();
System.out.print ("Test another palindrome (y/n)? ");
another = scan.nextLine();
}
}
}
Just to clarify what Jim Garrison said, the regex you need is the following
String m = "Madam, I'm'',.,.'' Adam";
m = m.toLowerCase().replaceAll("\\W", "");
This will leave only letters and digits and remove whitespace and punctuation, i.e. m will become "madamimadam" and you can run you regular palindrome test on that string.
You can learn more about regular expressions here
This looks like a really old post but I think I stumbled upon a simpler solution for a palindrome test. This checks the first and last characters and moves inwards and exits the program as soon as the characters do not match.
public class CharTest {
public static void main(String[] args) {
//converts string to lowercase and replaces everything except numbers
// and alphabets
String s = "Niagara. O roar again!".toLowerCase().replaceAll("\\W", "");
int j=0;
int k = s.length() - 1;
while(j < s.length() / 2) { //loops until half the length of the string if
//even and floor value if odd.
if (s.charAt(j++) != s.charAt(k--)){//check for first and last chars
//and go inwards. if char do not match print 'Not a Palindrome' and exit
System.out.println("Not a Palindrome");
System.exit(0);}
}
System.out.println("Palindrome"); //if every chars match print "Palindrome"
}
}
This code for determine if a word is a palindrome can be much more simplified. Find updated Code
String word;
int z;
int y = 0;
int i = 0;
char letter;
Scanner input = new Scanner(System.in);
System.out.print("Enter a word: ");
word = input.nextLine();
word = word.replaceAll("\\s+", "");
word = word.toLowerCase();
z = word.length()-1;
while (i <= z){
if ((letter = word.charAt(i)) == (letter = word.charAt(z-i))){
y += 1;
}
i += 1;
}
if (y == (z+1)){
System.out.println("The word IS a palindrome");
}
else{
System.out.println("The word is NOT a palindrome");
}
}
}
You could simplify the code significantly by removing all the spaces and punctuation before you start. Look at String.replaceAll(regex,replacement). You would write a regular expression to match blanks and punctuation, and provide an empty string ("") as the replacement. This will return a new string containing the original minus the characters you want to ignore.
This is the programming assignment from the Java Software Solutions (PP3.11) that I assign my students. Ironically the teacher solution uses Character.isLetterOrDigit(___) (which is never mentioned in the book) and uses methods to get rid of spaces and punctuation (having not even taught methods at that point in the book), and char is not an official part of the AP CS subset. Silly publishers.
Look at char's documentation entry. Specifically the isLetterOrDigit method. If that method returns false, then it's punctuation or a space. There are other methods in there as well that can help with that.
Your Problem: You are not ignoring the case of the letters. So if you try Able was I, ere I saw Elba, it will not come back correctly, although it is a true palindrome.