I have to make the code such that the user cannot enter a wrong value.
public static String getFraction() {
Scanner s = new Scanner(System.in);
String fraction = s.next();
if (validFraction(fraction)){
return fraction;
}
else {
System.out.print("Invalid fraction. Please enter a
fraction (a/b) or integer (a), where a and b are
integers and b is not zero : ");
getFraction();
}
Here when the user enters a wrong value it prompts the user to put a new value but it still takes the old value.
return null;
}
For example, say if I input a/b it prompts me to input again but since I use a parseInt method later in the code it shows me an error like :
Exception in thread "main" java.lang.NumberFormatException: For
input string: "a"
at java.base/java.lang.NumberFormatException.forInputString(Num
berFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at FractionCalculator.numerator(FractionCalculator.java:105)
at FractionCalculator.main(FractionCalculator.java:15)
Valid Fraction function :
public static boolean validFraction(String f) {
if (f.contains("/")) {
int n = f.indexOf("/");
String num = f.substring(0, n);
String den = f.substring(n+1);
for (int i = 1; i<n; i++) {
char a = num.charAt(i);
char b = den.charAt(i);
if (a == '-' || b == '-') {
return false;
}
}
f.replaceAll("[-]", "");
if (isNumber(num, den)) {
if (den.equals("0"))
return false;
else
return true;
}
}
else {
if (f.matches("^[0-9]+$"))
return true;
}
return false;
}
The exception seems to be coming from a place where Strings (a, b) are getting parsed as Integers.
If you intend to actually do so and check if the string is numeric or not, then it's advisable to catch NumberFormatException and return the status accordingly as follows:
private static boolean isNumber(String string)
{
try
{
Integer.parseInt(string);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
Related
Below are the code. To fix the error, I simply rewrote the code in getFraction() method to den = Integer.parseInt(fracValue.substring(fracValue.indexOf("/")+1, fracValue.length())) , by adding +1. I have never seen or learn this during my courses and I just encounter this while doing project. I want to understand what the code did in num = Integer.parseInt(fracValue.substring(0, fracValue.indexOf("/"))) and den = Integer.parseInt(fracValue.substring(fracValue.indexOf("/"), fracValue.length())), we are converting the numerator to int and the num is all the values before the / and the den is all the values after the /. Am I right ? My second question is that why do we need to add +1 after the indexOf("/") ? Is it so we are taking the values after the /?
import java.util.Scanner;
public class FractionCalculator {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args) {
intro();
while (true) {
String operation = getOperation();
Fraction frac1 = getFraction();
Fraction frac2 = getFraction();
Fraction result = new Fraction(1,1);
String result2 = "";
if (operation.equals("=")) {
System.out.println(frac1+" "+operation+" "+frac2+" is "+frac1.equals(frac2));
} else {
if (operation.equals("+")) {
result=frac1.add(frac2);
} else if (operation.equals("-")) {
result=frac1.subtract(frac2);
} else if (operation.equals("/")) {
if(frac2.getNumerator()==0) {
result2="Undefined";
} else {
result=frac1.divide(frac2);
}
} else if (operation.equals("*")) {
if(frac2.getNumerator()==0) {
result2 = "Undefined";
} else {
result=frac1.multiply(frac2);
}
}
//print results
} if (result2!="") {// division and multiplication by zero is undefined
System.out.println(frac1+" "+operation+" "+"0"+" = "+result2);
} else if (result.getNumerator()%result.getDenominator() == 0) {
System.out.println(frac1+" "+operation+" "+frac2+" = "+(result.getNumerator()/ result.getDenominator()));
} else {
System.out.println(frac1+" "+operation+" "+frac2+" = "+result.toString());
}
}
}
public static void intro() {
System.out.println("\nThis program is a fraction calculator");
System.out.println("It will add, subtract, multiply and divide fractions until you type Q to quit.");
System.out.println("Please enter your fraction in the form a/b, where a and b are integers.");
for (int i=0; i<80; i++) {
System.out.print("-");
}
}
public static String getOperation() {
System.out.println("\nPlease enter an operation (+, -, /, *, = or \"Q\" to quit): ");
Scanner input = new Scanner(System.in);
String operation = input.nextLine();
int x = 0;
while (x == 0) {
if (operation.equals("+") || operation.equals("-") || operation.equals("/") || operation.equals("*") || operation.equals("=")) {
x++;
} else if (operation.equalsIgnoreCase("q")) {
System.exit(0);
} else {
System.out.println("Invalid input, enter valid operation (+, -, /, *, = or \"Q\" to quit)");
operation = input.nextLine();
}
}
return operation;
}
public static boolean validFraction(String input) {
boolean valid;
if (input.startsWith("-")) {
input = input.replaceFirst("-",""); // or use 'input.substring("1", input.length())';
}
if (input.contains("-") || input.charAt(input.indexOf("/")+1)==('0') || input.contains(" ")) {
valid = false;
} else if (input.contains("/")) {
input = input.replace("/", "");
}
if (input.matches("^[0-9]+$") && input.length() > 0) {
valid = true;
} else {
valid = false;
}
return valid;
}
public static Fraction getFraction() {
System.out.println("Please enter a fraction (a/b) or integer (a): ");
String fracValue = input.nextLine();
//validate input
while (!validFraction(fracValue)) {
System.out.println("Please enter a fraction (a/b) or integer (a): ");
fracValue = input.nextLine();
}
//convert to numerator, denominator
int num = 0;
int den = 0;
if (fracValue.contains("/")) {
num = Integer.parseInt(fracValue.substring(0, fracValue.indexOf("/")));
den = Integer.parseInt(fracValue.substring(fracValue.indexOf("/"), fracValue.length()));
} else {
num = Integer.parseInt(fracValue);
den = 1;
}
// return fraction
Fraction fracConv = new Fraction(num, den);
return fracConv;
}
}
substring(int start, int end) includes the character at start and excludes the character at end. Since the integer cannot be parsed with a / in it, you need to do fracValue.indexOf("/")+1 to get just the numerical part of the denominator.
Firstly you have to understand your input
if your input is String a = "6+7", it means your string length is 3, and alloted indexes are 0,1 and 2
where 0 index is '6', 1 index is '+' and 2 index is '7'
So, when you use a.substring(0, a.indexOf("+")) it means you are saying
a.indexOf("+") = 1 index
you should get a string including '0' index but not 1 index, because substring works with inclusive first param and exclusive second param.
In case of this a.substring(a.indexOf("+")+1, a.length())
you don't want to include '+' in your denominator, So you should not include 1 index, that's why you are adding (+1) with indexof.
So, by adding +1 you are saying only pick value from a.indexOf("+") +1, i.e. 2 index,
and length of string is 3, which means you will get string inclusive of 2 index, i.e 7
if your input is "6 + 7" in that case you should use 'trim()' before using Integer.parseInt.
I need some major help.
My assignment is to recognize a lowercase string and return a true or false statement despite the presence of other characters or words. So far, I'm able to recognize the string in all lowercase, but my code still returns a TRUE value if the word is all uppercase; I only want it to recognize the lowercase values.
The assignment:
Write a program that takes in a string line and prints true if letters of my name (“john”) have appeared in the string in the same order, all in lowercase. Please note that there might be other characters between the letters of my name.
Here's my code:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
boolean output = Check();
if (output == true) {
System.out.println("true");
}
else if (output == false) {
System.out.println("false");
}
}
public static boolean Check() {
String random;
Scanner sc = new Scanner(System.in);
random = sc.nextLine();
String word = "john";
for (int i = 0; i < word.length(); i++) {
if (random.contains(word.substring((i)))) {
return true;
}
}
if (random.contains("JOHN")) {
return false;
}
return false;
}
}
Any help would be great thanks.
Some sample outputs:
Sample Input 1:
hello John
Sample Output 1:
false
Sample Input 2:
j123o23h56n
Sample Output 2:
true
Sample Input 3:
joh'n
Sample Output 3:
true
Sample Input 4:
ho0jn
Sample Output 4:
false
Sample Input 5:
J2j##oh123$NNNnn
Sample Output 5:
true
You need to write a logic where you pick each char from "john" string and compare it in order whether all of them occurred in that order or not. The moment it finds all the characters are found in the input string, it immediately return true without the need to further scan the input string. You may write something like this,
public static boolean Check() {
String random;
Scanner sc = new Scanner(System.in);
random = sc.nextLine();
String word = "john";
sc.close();
int findIndex = 0;
char findChar = word.charAt(findIndex);
for (char c : random.toCharArray()) {
if (findChar == c) {
findIndex++;
if (findIndex == word.length()) {
return true;
}
findChar = word.charAt(findIndex);
}
}
return false;
}
You can simply do this (I didn't understand your condition for uppercase though; this Check method can find whether j,o,h,n appear in the string in the proper order),
public static boolean Check(){
String random;
Scanner sc = new Scanner(System.in);
random = sc.nextLine();
HashMap<String, Boolean> map =new HashMap<String, Boolean>();
for(int i=0;i<random.length();i++){
if(map.size() == 0){
//find j
if(random.charAt(i) == 'j'){
map.put("j", true);
}
}else if(map.containsKey("j") && map.size() == 1){
//find o
if(random.charAt(i) == 'o'){
map.put("o", true);
}
}else if(map.containsKey("o")&& map.size() == 2){
//find h
if(random.charAt(i) == 'h'){
map.put("h", true);
}
}else if(map.containsKey("h")&& map.size() == 3){
//find n
if(random.charAt(i) == 'n'){
map.put("n", true);
}
}
}
return map.size() == 4;
}
Alternatively, you can use a stack to solve this too,
public static boolean Check(){
String random;
Scanner sc = new Scanner(System.in);
random = sc.nextLine();
ArrayDeque<Character> stack = new ArrayDeque<Character>();
stack.push('n');
stack.push('h');
stack.push('o');
stack.push('j');
for(int i=0;i<random.length();i++){
if(random.charAt(i) == stack.peek()){
stack.pop();
}
if(stack.size() == 0){
return true;
}
}
return false;
}
I am trying to write a method that asks a user for a positive integer. If a positive integer is not inputted, a message will be outputted saying "Please enter a positive value". This part is not the issue. The issue is that when I try to implement a try catch statement that catches InputMismatchExceptions (in case user inputs a character or string by accident), the loop runs infinitely and spits out the error message associated with the InputMistmatchException.
Here is my code:
private static int nonNegativeInt(){
boolean properValue = false;
int variable = 0;
do {
try {
while (true) {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
} else if (variable >= 0) {
break;
}
}
properValue = true;
} catch (InputMismatchException e){
System.out.println("That is not a valid value.");
}
} while (properValue == false);
return variable;
}
Essentially what is happening is that the scanner runs into an error when the given token isn't valid so it can't advance past that value. When the next iteration starts back up again, scanner.nextInt() tries again to scan the next input value which is still the invalid one, since it never got past there.
What you want to do is add the line
scanner.next();
in your catch clause to basically say skip over that token.
Side note: Your method in general is unnecessarily long. You can shorten it into this.
private static int nonNegativeInt() {
int value = 0;
while (true) {
try {
if ((value = scanner.nextInt()) >= 0)
return value;
System.out.println("Please enter a positive number");
} catch (InputMismatchException e) {
System.out.println("That is not a valid value");
scanner.next();
}
}
}
you are catching the exception but you are not changing the value of variable proper value so the catch statement runs forever. Adding properValue = true; or even a break statement inside the catch statement gives you the required functionality!
I hope I helped!
You can declare the scanner at the start of the do-while-loop, so nextInt() will not throw an exception over and over.
private static int nonNegativeInt(){
boolean properValue = false;
int variable = 0;
do {
scanner = new Scanner(System.in);
try {
while (true) {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
} else if (variable >= 0) {
break;
}
}
properValue = true;
} catch (InputMismatchException e){
System.out.println("That is not a valid value.");
}
} while (properValue == false);
return variable;
}
This is indeed nearly identical to SO: Java Scanner exception handling
Two issues:
You need a scanner.next(); in your exception handler
... AND ...
You don't really need two loops. One loop will do just fine:
private static int nonNegativeInt(){
boolean properValue = false;
int variable = 0;
do {
try {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
continue;
} else if (variable >= 0) {
properValue = true;
}
} catch (InputMismatchException e){
System.out.println("That is not a valid value.");
scanner.next();
}
} while (properValue == false);
return variable;
}
Just add a break statement inside your catch.
Btw, you can get rid of the while loop by rewriting it like this:
try {
variable = scanner.nextInt();
if (variable < 0) {
System.out.println("Please enter a positive value");
} else {
properValue = true;
}
}
//...
I have seen this asked 2x, but the correct response I need has not been addressed.
In this assessment,
you will design and code a Java console application that
validates the data
entry
of a course code (like IT4782)
and
report
back if the
course code is valid or
not
valid.
The
application
uses the Java char
and
String data types to implement
the validation.
You
can
use
either
the
Toolwire environment
or your
local
Java
development
environment
to complete this
assignment.
The requirements of
this application are
as follows:
The application is to read
a course code
entered
by the user
from the
keyboard.
The course code
is made
of 5 characters and should
follow
these
Rules:
First
character
is always
an
upper
case I
or a lower
case i
Second character
is always an upper
case
T or
a lower
case t
Third,
fourth,
fifth,
and sixth characters
are always digits (0-
9)
The application then validates the course code against
above the rules and prints a
message
If the
course code
is valid
or not.
If the course code is not
valid,
the application should print
a message
explaining why
the course
code is not
valid.
Output should look like this:
Here is my code, I cannot get the code to produce the pictured results. It outputs all the invalid messages.
package u4a1_validatecoursecode;
import java.util.Scanner;
public class U4A1_ValidateCourseCode {
public static void main(String[] args) {
// Larry Copy
Scanner s = new Scanner(System.in);
System.out.print("Enter a course code to validate (e.g. IT4782) : ");
String code = s.nextLine();
if (validateCode(code)) {
System.out.println("Course code: " + "" + code + "" + " is valid.");
} else {
System.out.println("Not valid code");
}
}
private static boolean validateCode(String code) {
if (code.length() != 6) {
return false;
} else {
//First character is always an upper case I or a lower case i
if (code.charAt(0) != 'I' && code.charAt(0) != 'i') {
return false;
}
System.out.println("integer is not an I or i");
// Second character is always an upper case T or a lower case t
if (code.charAt(1) != 'T' && code.charAt(1) != 't') {
return false;
}
System.out.println("integer is not a T or t");
// Third, fourth, fifth, and sixth characters are always digits (0-9)
if (!Character.isDigit(code.charAt(2))) {
return false;
}
System.out.println("integer 3 is not a number");
if (!Character.isDigit(code.charAt(3))) {
return false;
}
System.out.println("integer 4 is not a number");
if (!Character.isDigit(code.charAt(4))) {
return false;
}
System.out.println("integer 5 is not a number");
if (!Character.isDigit(code.charAt(5))) {
return false;
}
System.out.println("integer 6 is not a number");
return false;
}
}
}
When you return false; the code after is not executed so you'll never see why it returns
If you return only false the test will never pass, you need a variable to validate or not the code
If it goes in one if (not valid) you'll get the message, and the valid will be false
private static boolean validateCode(String code) {
if (code.length() != 6) {
return false;
} else {
boolean valid = true;
//First character is always an upper case I or a lower case i
if (code.charAt(0) != 'I' && code.charAt(0) != 'i') {
System.out.println("integer is not an I or i");
valid = false;
}
// Second character is always an upper case T or a lower case t
if (code.charAt(1) != 'T' && code.charAt(1) != 't') {
System.out.println("integer is not a T or t");
valid = false;
}
// Third, fourth, fifth, and sixth characters are always digits (0-9)
if (!Character.isDigit(code.charAt(2))) {
System.out.println("integer 3 is not a number");
valid = false;
}
if (!Character.isDigit(code.charAt(3))) {
System.out.println("integer 4 is not a number");
valid = false;
}
if (!Character.isDigit(code.charAt(4))) {
System.out.println("integer 5 is not a number");
valid = false;
}
if (!Character.isDigit(code.charAt(5))) {
System.out.println("integer 6 is not a number");
valid = false;
}
return valid;
}
}
You are using too much line of code:
Here what I do:
private static boolean validateCode(String code,String validCode) {
boolean b=true;
if (code.length() != 6) {
return false;
}
for(int i=0;i<code.length();i++){
if(code.toLowerCase().charAt(i)!=validCode.toLowerCase().charAt(i) && i<2){
System.out.println("Character at "+i+" position is not an "+ validCode.charAt(i));
b= false;
}
if(Character.isDigit(code.charAt(i)) && i>2){
System.out.println("Character at "+i+" is not a digit");
b= false;
}
}
return b;
}
I'm trying to give the user an infinite amount of inputs until they enter q. I'm using a while statement to run the program, but when the user tries to quit I get an error because the program would try and parse q as an integer. Any ideas on how I should change the structuring of this to prevent the error from occurring?
Scanner in = new Scanner(System.in);
System.out.println("What would you like your Fibonacci number to be?(enter q to quit)");
String value = in.next();
int trueValue;
while(!value.equalsIgnoreCase("q")) {
trueValue = Integer.parseInt(value);
Fibonacci userCase = new Fibonacci(trueValue);
System.out.println(userCase.calculateFibonacci(userCase.getCaseValue()));
System.out.println("Please enter another number.");
value = in.next();
trueValue = Integer.parseInt(value);
}
If it matters, here are the methods being called within the loop.
public int calculateFibonacci(int caseValue) {
if(caseValue == 0)
return 0;
else if(caseValue == 1)
return 1;
else
return calculateFibonacci(caseValue-1) + calculateFibonacci(caseValue-2);
}
public int getCaseValue()
{
return caseValue;
}
You can remove the last
trueValue = Integer.parseInt(value);
since you are already doing that at the start of the loop.
do{ getting the user value before checking } while(checking if it's ok);
/* https://stackoverflow.com/questions/40519580/trying-to-determine-if-a-string-is-an-integer */
private boolean isInteger(String str) {
if(str == null || str.trim().isEmpty()) {
return false;
}
for (int i = 0; i < str.length(); i++) {
if(!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
public static String check(Scanner in) {
String value;
do {
System.out.println("Please enter a number or q to quit.");
value = in.next();
} while(!value.equalsIgnoreCase("q") && !isInteger(value));
return value;
}
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
String value = check(in);
while(!value.equalsIgnoreCase("q")) {
Fibonacci userCase = new Fibonacci(Integer.parseInt(value));
System.out.println(userCase.calculateFibonacci(userCase.getCaseValue()));
value = check(in);
}
in.close();
}