Why will my java program not accept alphabetical input from the user? - java

Edit: my problem has been partially fixed. Now I am able to enter text, however nothing reads after I enter the 'shiphalf' value. Did I construct my if else statements incorrectly?
I am attempting to let people input a coupon code but I am unable to figure out how to let the console know that the user is inputting text. I feel that the error is somewhere in here:
System.out.println("Enter a Coupon Code: ");
String ship = input.nextLine();
But I am not entirely sure. Here is the whole source code below:
package pseudoPackage;
import java.util.Scanner;
public class PseudoCode {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int ship1 = 0;
int ship2 = 6;
int ship3 = 2;
String shiphalf = null;
System.out.print("How much will shipping cost you?");
System.out.println();
System.out.print("Enter your textbook cost in dollars without the $: ");
double cost = input.nextDouble();
if ( cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( cost < 100 && cost > 50 ) {
System.out.println("Your shipping cost is $6");
} else if ( cost < 50 ) {
System.out.println("Your shipping cost is $2");
}
System.out.println("Enter a Coupon Code: ");
String ship = input.nextLine();
if ( ship == shiphalf && cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( ship == shiphalf && cost < 100 && cost >50 ) {
System.out.println("Your shipping costs are $3 ");
} else if ( ship == shiphalf && cost < 50 ) {
System.out.println("Your shipping costs are $1");
}
}
}

You have 2 problems in your code:
1. Use input.next() instead of input.nextLine().
2. Change your if conditional to ship.equals("shiphalf"). Remember that you use .equals() to compare 2 strings.
Here is your final code:
package pseudoPackage;
import java.util.Scanner;
public class PseudoCode {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int ship1 = 0;
int ship2 = 6;
int ship3 = 2;
String shiphalf = null;
System.out.print("How much will shipping cost you?");
System.out.print("\nEnter your textbook cost in dollars without the $: ");
double cost = input.nextDouble();
if ( cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( cost < 100 && cost > 50 ) {
System.out.println("Your shipping cost is $6");
} else if ( cost < 50 ) {
System.out.println("Your shipping cost is $2");
}
System.out.println("Enter a Coupon Code: ");
String ship = input.next();
if ( ship.equals("shiphalf") && cost >= 100 ) {
System.out.println("Your shipping costs are $0");
} else if ( ship.equals("shiphalf") && cost < 100 && cost >50 ) {
System.out.println("Your shipping costs are $3 ");
} else if ( ship.equals("shiphalf") && cost < 50 ) {
System.out.println("Your shipping costs are $1");
}
}
}

What happens here is the following:
when you call
double cost = input.nextDouble();
Your Scanner reads the next Double in the Console and then "stops" at the end of that double value. It does not enter a new Line.
Looking at the Java Documentation, we can see that the Method nextLine() is partly described the following way:
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end
So if your Scanner still is in a line, and you call nextLine() it will simply return the rest of the line. In your case this would most likely just be an empty String, even though you wish to read the Coupon Code.
After that your Scanner points to the actual line in the console you wanted to read.
So what's the easiest way to work around this ? You can just invoke the Method nextLine() once more before you get the Input for the Coupon Code. This will set your Scanner to the beginning of the actual line you wish to read.

Another way to get text from a user is to use JOptionPane. Also if you are comparing text, you want to code ' ship.equals(shiphalf) '
String x = JOptionPane.showInputDialog(null, "Type something!");
if(ship.equals(x)){
System.out.println("Your code works");
}
Hope this kind of helps?

Related

Multiple Scanner Inputs: Iterative validation of current selection blocks

I am attempting to validate multiple scanner inputs with paired If-Else blocks in a single while loop. The behavior that I am interested in achieving is to the current validation If-Statement request the user to re-enter input or move on to the subsequent input / selection blocks.
Right now, I am using the continue keyword which returns to the beginning of the While loop. Would using a do...while loop be better suited for this? Thank you.
while (count < numCars) {
System.out.println("Enter car type");
String name = scanner.next();
if (name.matches(".*\\d")) {
System.out.println("Name entry cannot contain numbers");
continue;
} else {
// re-enter name
}
System.out.println("Enter max speed");
int maxSpeed = scanner.nextInt();
if (maxSpeed == 100 || maxSpeed > 100) {
System.out.println("Max speed is not valid. Please re-enter");
continue;
} else {
// re-enter age
count++;
}
}
The functionality you want for every block can be achieved using while instead of if-else statements. I also structured your code in a nicer/more organized way:
int count = 0, numCars = 3; // Example value
String name;
int maxSpeed;
while (count < numCars) {
System.out.print("Enter car type: ");
name = scanner.next();
scanner.nextLine(); // Cleans the buffer
while (name.matches(".*\\d")) {
System.out.println("Name entry cannot contain numbers.");
System.out.print("Enter car type: ");
name = scanner.next();
scanner.nextLine(); // Cleans the buffer
}
System.out.print("Enter max speed: ");
maxSpeed = scanner.nextInt();
while (maxSpeed >= 100) {
System.out.println("Max speed is not valid. Please re-enter.");
System.out.print("Enter max speed: ");
maxSpeed = scanner.nextInt();
}
count++;
}

Average Calculator Program Using Java

import java.util.Scanner;
public class AverageMark{
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int mark[] = { 0, 0, 0, 0 };
System.out.printf("Enter integer mark %s between 0 and 100: ", i + 1);
}
System.out.println("Thanks for entering your marks.\n");
double average = (mark[0] + mark[1] + mark[2] + mark[3]) * 0.25;
String grade;
if (average >= 90) {
grade = "A+";
} else if (average >= 80) {
grade = "A";
} else if (average >= 70) {
grade = "B";
} else if (average >= 60) {
grade = "C";
} else if (average >= 50) {
grade = "D";
} else
grade = "F";
System.out.printf("Your average is: %.2f\n", average);
System.out.printf("Your average of %.2f has a letter grade of %s", average, grade);
}
}
//Hi sorry about the prior edit, I am new to this site. This is the code I wrote but I'm not sure why it won't run. It seems something might be missing but I'm
quite unclear. Please help thank you
Your code is almost there, just missing to store the values entered by user :
Store the marks in the array :
System.out.println("Enter the marks : ");
for (int i =0; i < mark.length; i ++) {
System.out.printf("Enter integer mark %s between 0 and 100: ", i + 1);
// assign each input to an index of the array
mark[i] = input.nextInt();
}
I would also advice you to declare the array like below rather than just initialing all the indexes to 0
int mark[] = new int[4];
The rest of your code works as it is.
There are some issues with the code.
The first error you see is:
AverageMark.java:13: error: <identifier> expected
System.out.println("Thanks for entering your marks.\n");
This is because you have a closing curly brace where it is not needed. The Java compiler is having difficulty interpreting the structure of your program. Remove line 11. You need to have matching curly braces to form a syntactically correct program. Did you mean to include a for loop ?
Once you correct that and recompile you'll find that:
AverageMark.java:10: error: cannot find symbol
System.out.printf("Enter integer mark %s between 0 and 100: ", i + 1);
symbol: variable i location: class AverageMark 1 error
Add the definition for int i=0 before the reference to i on line 10.
It should then compile and you can start debugging.
In below program , I am giving flexibility to user to enter number of subjects. Scanner allows the user to read values of various types. System.in: An InputStream which is typically connected to keyboard input of console program.
import java.util.Scanner;
class AverageMarks
{
public static void main(String args[])
{
int i;
System.out.println("Enter number of subjects");
Scanner sc=new Scanner(System.in);
//Here we are taking number of subjects from user
int n=sc.nextInt();
//Set array to no of subject
int[] a=new int[n];
double avg=0;
System.out.println("Enter marks");
// Taking marks from user for n no of subjects
for( i=0;i<n;i++)
{
a[i]=sc.nextInt();
}
// Calculating total marks of subjects in avg variable
for( i=0;i<n;i++)
{
avg=avg+a[i];
System.out.println("Total marks of subjects : => "+avg);
}
//Calculating average % using total/no of subject formula
for(i=0;i<n-1;i++)
{
System.out.print(a[i]+",");
}
System.out.println(a[i]+") ="+avg/n);
}
}

Using "while (x || y)" Loop in Java

I have a project for my AP Compsci class in which we are required to input the cost of an item from a soda machine and return the change for the amount paid.
I'm having a bit of problem with the input, however; I am using a while loop to ensure that the input is a double, and that the value for the amount paid is greater than or equal to the cost. When I test this out, it seems that the I have to enter the amount paid multiple times in order for it to be scanned (see lines 23-30).
I have tried moving the "scan.next()" to different places within the loop, as well as changing the "scan.next()" to a "scan.nextLine" but both have just introduced more problems. Does anyone happen to know a way that I can check if the input is either not a double or less than the cost, and if so prompt the user to input the value again? I've pasted my code below:
import java.util.Scanner;
import java.lang.Math;
public class Sodamachine
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("SODA MACHINE: V1.2");
System.out.println("Input the cost of the soda can and the amount you put in and your change will");
System.out.println("be output.");
System.out.print("\nEnter cost of purchase below:\n$");
while (! scan.hasNextDouble())
{
System.out.println("ERROR: Input was not a real number.");
System.out.print("Enter cost of purchase below:\n$");
scan.nextLine();
}
double cost = scan.nextDouble();
//this is where the problem starts
System.out.print("Enter amount paid below:\n$");
while ((! scan.hasNextDouble()) || (scan.nextDouble() < cost))
{
System.out.println("ERROR: Improper input.");
System.out.print("Enter amount paid below:\n$");
scan.next();
}
double paid = scan.nextDouble();
}
}
Please try my very basic and similar solution.
Requirements: totalCost and totalPaid values have to be DOUBLE variables.
In case those variables are not DOUBLE, the program stops and you should run it again (of course you can add a loop of other logic and call totalCost and totalPaid many times).
Basic assumption of my solution: totalPaid > totalCost.
Of course you can change and improve my code. This solution is only an idea how your problem can be solved.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("SODA MACHINE: V1.2");
System.out.println("Input the cost of the soda can and the amount you put in and your change will");
System.out.println("be output.");
double totalCost = 0.0;
System.out.print("\nEnter cost of purchase below:\n$");
try{
totalCost = scan.nextDouble();
}
catch (Exception e)
{
System.out.println("ERROR: Input was not a real number - please provide DOUBLE value.");
System.exit(0);
}
System.out.print("Enter amount paid below:\n$");
double totalPaid = 0.0;
try{
totalPaid = scan.nextDouble();
}
catch (Exception e)
{
System.out.println("ERROR: Input was not a real number - please provide DOUBLE value.");
System.exit(0);
}
System.out.println("Change:\n$" + (totalPaid - totalCost));
}
You want to avoid scanning multiple times in the while loop.Suppose your cost is 100 and paid is 90. So your while loop is going to go
scan.nextDouble() < cost) <-- first scan, which is less than cost,
scan.next(); <-- Second scan.
scan.nextDouble() < cost) <-- Back to the while loop condition and you have an extra scan!
double paid = scan.nextDouble(); <-- And when you exit the while loop, you have another extra scan!
Ideally, you scan once, and if your conditions are not met, scan again for the new input.
//method to check if String can be converted to Double
public static boolean isDouble(String input){
try{
Double.parseDouble(input);
}catch(NumberFormatException e){
return false;
}
return true;
}
String paid = scan.next(); //scan once
//while not double or paid less than cost, scan again
while (!isDouble(paid) || (Double.parseDouble(paid) < cost) ){
System.out.println("Wrong paid number");
paid = scan.next();
}
double paidDouble = Double.parseDouble(paid);

Java GPA calculator/take all grade strings in order to create final gpa/Scanner/String

I've been having trouble with this problem in which:
Whenever I input a series of string letters, it simply lists 0.0 as the gpa, when it should vary.
When I input B B C B F into the program,
it inputs your GPA is 0.0, although it should be at least higher than 2.0
I have to
write a program that accepts the letter grades for a student,
calculates the student's gpa,
and prints it out,
along with one of the following five messages:
Eligible.
Ineligible, taking less than 4 classes.
Ineligible, gpa below 2.0.
Ineligible, gpa above 2.0 but has F grade (note: gpa >= 2.0).
Ineligible, gpa below 2.0 and has F grade.
The message "Ineligible, taking less than 4 classes" has priority over the other 3 ineligible cases.
The class will not ask the user for how many grades are in a student's report
card.
The program will continue to read grades until a non-grade character is input.
At this point, some type of loop will cease and the program prints the GPA value and the eligibility message.
Example of run output: GPA = 3.75 Eligible
I do not have to print out any of the individual grades.
so far I have gotten this:
import java.util.Scanner;
import java.lang.String;
public class P4_Icel_Murad_totals
{
public static void main(String[] args){
double gpa = 0;
double input = 0;
String total = "";
int classes = 0;
boolean fail = false;
do{
Scanner in = new Scanner (System.in);
System.out.print("Please enter All class totals in letter form(type stop to stop): ");
total = in.nextLine();
total = total.toLowerCase();
if(total.equals('a')){
input = 4.0;
}else if (total.equals('b')){
input = 3.0;
}else if (total.equals('c')){
input = 2.0;
}else if (total.equals('d')){
input = 1.0;
}else if (total.equals('f')){
fail = true;
}
gpa += input;
classes++;
}while (!total.equals("stop"));
System.out.println("Your GPA is: " + gpa + " ");
if (gpa >= 2 && classes >= 4 && fail == false){
System.out.println("Eligible");
}else if(classes < 4){
System.out.println("Ineligible, taking less than 4 classes");
}else if(gpa < 2.0 && fail == false && classes >= 4 ){
System.out.println("Ineligible, gpa below 2.0");
}else if(gpa >= 2.0 && fail != false && classes >= 4 ){
System.out.println("Ineligible, gpa above 2.0 but has F grade (note: gpa >= 2.0");
}else if(gpa < 2.0 && fail != false && classes >= 4 ){
System.out.println("Ineligible, gpa below 2.0 and has F grade");
}
}
}
The string you are entering is "B B C B F" so when you are trying to with the individual letters you are essentially doing if ("b b c b d".equals("a")) etc.
To split the string you can use .split(" ")
String grades[] = total.split(" ");
will produce an array containing each letter. You will then need to loop over each one and add this to the gpa total.
total = total.toLowerCase();
String grades[] = total.split(" ");
for (String grade : grades){
if (grade.equals("a")) {
input = 4.0;
} else if (grade.equals("b")) {
input = 3.0;
} else if (grade.equals("c")) {
input = 2.0;
} else if (grade.equals("d")) {
input = 1.0;
} else if (grade.equals("f")) {
fail = true;
input = 0.0; //needed as if it fails it will still add previous value onto total
}
gpa += input;
classes++;
}
The current misbehaviour stems from the implementation of the equals()-method in String. From the Java documentation:
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
What happens: The char literal becomes a Character object, when it is passed to equals(). A Character object is not an instance of String, so equals() returns false by design.

how to only allow one argument at a time

I am allowing the user to enter numbers via command line. I would like to make it so when the user enters more then one number on the command line at a time it displays a message asking for one number then press enter. then carries on.
here is my code. If someone could show me how to implement this I would appreciate it.
import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.Scanner;
class programTwo
{
private static Double calculate_average( ArrayList<Double> myArr )
{
Double sum = 0.0;
for (Double number: myArr)
{
sum += number;
}
return sum/myArr.size(); // added return statement
}
public static void main( String[] args )
{
Scanner scan = new Scanner(System.in);
ArrayList<Double> myArr = new ArrayList<Double>();
int count = 0;
System.out.println("Enter a number to be averaged, repeat up to 20 times:");
String inputs = scan.nextLine();
while (!inputs.matches("[qQ]") )
{
if (count == 20)
{
System.out.println("You entered more than 20 numbers, you suck!");
break;
}
Scanner scan2 = new Scanner(inputs); // create a new scanner out of our single line of input
try{
myArr.add(scan2.nextDouble());
count += 1;
System.out.println("Please enter another number or press Q for your average");
}
catch (InputMismatchException e) {
System.out.println("Stop it swine! Numbers only! Now you have to start over...");
main(args);
return;
}
inputs = scan.nextLine();
}
Double average = calculate_average(myArr);
System.out.println("Your average is: " + average);
}
}
As suggested in the comments to the question: Just do not scan the line you read for numbers, but parse it as a single number instead using Double.valueOf (I also beautified the rest of your code a little, see comments in there)
public static void main( String[] args )
{
Scanner scan = new Scanner(System.in);
ArrayList<Double> myArr = new ArrayList<Double>();
int count = 0;
System.out.println("Enter a number to be averaged, repeat up to 20 times:");
// we can use a for loop here to break on q and read the next line instead of that while you had here.
for (String inputs = scan.nextLine() ; !inputs.matches("[qQ]") ; inputs = scan.nextLine())
{
if (count == 20)
{
System.out.println("You entered more than 20 numbers, you suck!");
break;
}
try{
myArr.add(Double.valueOf(inputs));
count++; //that'S even shorter than count += 1, and does the exact same thing.
System.out.println("Please enter another number or press Q for your average");
}
catch (NumberFormatException e) {
System.out.println("You entered more than one number, or not a valid number at all.");
continue; // Skipping the input and carrying on, instead of just starting over.
// If that's not what you want, just stay with what you had here
}
}
Double average = calculate_average(myArr);
System.out.println("Your average is: " + average);
}
(Code untested, so there may be errors in there. Please notify me if you got one ;))
String[] numbers = inputs.split(" ");
if(numbers.length != 1){
System.out.println("Please enter only one number");
}

Categories