String contains nothing or the user just presses enter - java

I have been looking for solution and tried it on my code, but still no luck found. What I want to do is to throw an exception if the user inputs nothing and just presses enter and a catch block will be executed once it throws the exception. But in my case, it only executes the second catch-block I have which is the InvalidAnswerException instead of BlankException
Code:
import java.util.Scanner;
public class QnA {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
String[] questions = { "Question-1: Who is the national hero of the Philippines?", "Question-2: What is the national Anthem of the Philippines ?",
"Question-3: What is the national sport of the philippines ?"};
String choices[][] = { { "A)Jose Rizal", "B)Andres Bonifacio", "C)Lapu-Lapu" },
{ "A)Paro-Paro G", "B)Bahay kubo", "C)Lupang Hinirang" }, { "A)Basketball", "B)Arnis", "C)Badminton" }, };
char answers[] = {'A', 'B', 'C'};
int score = 0;
for (int i = 0; i < 3; i++) {
while (true) {
System.out.println(questions[i]);
for (int j = 0; j < 3; j++)
System.out.println(choices[i][j]);
System.out.print("Your Answer : ");
String ans = sc.nextLine();
try {
if (ans.contains("A") || ans.contains("a") || ans.contains("B") || ans.contains("b") || ans.contains("C") || ans.contains("c")) {
score++;
break;
}
if (ans.matches("[0-9]") || ans.matches("[!##$%&*()_+=|<>?{}\\\\[\\\\]~-]")) {
throw new InvalidInputException("");
}
if (!ans.equalsIgnoreCase("A") || !ans.equalsIgnoreCase("B") || !ans.equalsIgnoreCase("C")) {
throw new InvalidAnswerException("");
}
if (ans.length() == 0) {
throw new BlankException("");
}
} catch (InvalidInputException e) {
System.out.println("InvalidInputException,Try again..");
continue;
} catch (InvalidAnswerException e) {
System.out.println("InvalidAnswerException,Try again..");
continue;
} catch(BlankException e) {
System.out.println("BlankException,Try again..");
continue;
}
}
}
System.out.println("Your score out of " + questions.length + " is : " +score);
sc.close();
}
}
class InvalidInputException extends Exception {
public InvalidInputException(String message) {
super(message);
}
}
class InvalidAnswerException extends Exception {
public InvalidAnswerException(String message) {
super(message);
}
}
class BlankException extends Exception {
public BlankException(String message) {
super(message);
}
}

As #Ole V.V. pointed out, your last if (ans.legnth() == 0) condition is not applied because it is not even reached by your program. When user inputs nothing "" your ans variable becomes ans="" and then it applies to the third condition if (!ans.equalsIgnoreCase("A") || !ans.equalsIgnoreCase("B") || !ans.equalsIgnoreCase("C")). The simplest solution of this is to put your last if before any other. So, your code may be changed like that:
while (true) {
System.out.println(questions[i]);
for (int j = 0; j < 3; j++)
System.out.println(choices[i][j]);
System.out.print("Your Answer : ");
String ans = sc.nextLine();
try {
if (ans.contains("A") || ans.contains("a") || ans.contains("B") || ans.contains("b") || ans.contains("C") || ans.contains("c")) {
score++;
break;
}
if (ans.length() == 0) {
throw new BlankException("");
}
if (ans.matches("[0-9]") || ans.matches("[!##$%&*()_+=|<>?{}\\\\[\\\\]~-]")) {
throw new InvalidInputException("");
}
if (!ans.equalsIgnoreCase("A") || !ans.equalsIgnoreCase("B") || !ans.equalsIgnoreCase("C")) {
throw new InvalidAnswerException("");
}
} catch (InvalidInputException e) {
System.out.println("InvalidInputException,Try again..");
continue;
} catch (InvalidAnswerException e) {
System.out.println("InvalidAnswerException,Try again..");
continue;
} catch(BlankException e) {
System.out.println("BlankException,Try again..");
continue;
}
}

Related

What changes do I make to my code to allow more than one word to be translated to Pig Latin and printed?

I made a Java Script that took word input and turned it into a Pig Latin version of said word:
import java.util.Scanner;
class Main {
static Scanner myObj = new Scanner(System.in);
static boolean isVowel(char c) {
return (c == 'A' || c == 'a' || c == 'E' || c == 'e' || c == 'I' || c == 'i' || c == 'O' || c == 'o' || c == 'U'
|| c == 'u');
}
static String pigLatin(String oldWord) {
System.out.println("\r\n");
System.out.println("What word should I translate?");
oldWord = myObj.nextLine();
System.out.println("");
try {
Thread.sleep(800);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print("\r\n");
System.out.print("\r\n");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
int len = oldWord.length();
int index = -1;
for (int i = 0; i < len; i++) {
if (isVowel(oldWord.charAt(i))) {
index = i;
break;
}
}
if (index == -1)
return "-1";
return oldWord.substring(index) + oldWord.substring(0, index) + "ay";
}
public static void main(String[] args) {
String newWord = pigLatin("graphic");
if (newWord == "-1")
System.out.print("No vowels found. Pig Latin not possible");
else {
System.out.print("Your word in Pig Latin is: \033[1m" + newWord + "\033[0m");
}
}
}
This takes whatever is typed, moves all characters before the first vowel to the end, and then adds "ay" to it. I am now trying to change this to make it translate a sentence instead, so I decided to try using a string array for this, but I probably did something stupid or missed something important because I ended up with this code:
import java.util.Scanner;
class Main {
static Scanner myObj = new Scanner(System.in);
static boolean isVowel(char c) {
return (c == 'A' || c == 'a' || c == 'E' || c == 'e' || c == 'I' || c == 'i' || c == 'O' || c == 'o' || c == 'U'
|| c == 'u');
}
static String pigLatin(String sentance) {
System.out.println("\r\n");
System.out.println("What sentance should I translate?");
String oldWord = myObj.nextLine();
System.out.println("");
try {
Thread.sleep(800);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.print("\r\n");
System.out.print("\r\n");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(e);
}
String[] words = oldWord.split(" ");
for (String word : words) {
int len = word.length();
int index = -1;
for (int i = 0; i < len; i++) {
if (isVowel(word.charAt(i))) {
index = i;
break;
}
}
if (index == -1)
return "-1";
return word.substring(index) + word.substring(0, index) + "ay";
}
return words.toString();
}
public static void main(String[] args) {
String newWord = pigLatin("graphic");
System.out.print("Your sentance in Pig Latin is: \033[1m" + newWord + "\033[0m");
}
}
Which just made it only translate the first word and delete the rest. I'm still new to Java, and I have no idea how to fix this problem.
The reason why the code will just return the first word and stop processing the remaining lies here:
String[] words = oldWord.split(" ");
for (String word : words) {
int len = word.length();
int index = -1;
for (int i = 0; i < len; i++) {
if (isVowel(word.charAt(i))) {
index = i;
break;
}
}
if (index == -1)
return "-1"; // Stop processing anymore
return word.substring(index) + word.substring(0, index) + "ay"; // Stop processing anymore
}
The above is the for-loop that processes all the separate words from your sentence. However, a return statement will stop proceeding your pigLatin() function further and directly returns that value. So if you want to process all words from the sentence, you must not call return within the for-loop.
So what you can do, is to create another variable to hold your processed words. Like:
String[] words = oldWord.split(" ");
// Create another String array to hold your processed words
String[] pigLatinWords = new String[words.length];
int wordCounter = 0;
for (String word : words) {
int len = word.length();
int index = -1;
for (int i = 0; i < len; i++) {
if (isVowel(word.charAt(i))) {
index = i;
break;
}
}
if (index == -1) {
// Store the processed word in this new Array
pigLatinWords[wordCounter++] = word;
// Continue with the for-loop without processing the code below
continue;
}
// Store the processed word in this new Array
pigLatinWords[wordCounter++] = word.substring(index) + word.substring(0, index) + "ay";
}
And at the end you should call return like:
return String.join(" ", pigLatinWords);
Or you should refer to this to implement your own concatenation function if you are using Java 7 or below.
Changing the above code should produce a result matching with your expectation:
What sentance should I translate?
graphic graphic
...
Your sentance in Pig Latin is: aphicgray aphicgray
And note that you should not call toString() on String[], or you will end up having something like the hexadecimal hashcode of String[] printed:
Your sentance in Pig Latin is: [Ljava.lang.String;#7a79be86

IndexOutOfBound error with string manipulation

this is the code for a pig-latin translator in JAVA, it works with one word but never with a sentence. It seems that the code at line 30 is messing everything up, and I'm not sure how it is doing that or how I can fix it. IndexOutOfBoundError on line 8 and line 30. I'm not sure how to fix this, help.
public class Practice
{
public static void main(String[] args)
{
String a = "hello Stranger";
System.out.println(translate(a)); //8
}
private static String translate(String a)
{
String XD = a;
boolean repeat = true;
int first = 1;
int second = 0;
do
{
second = XD.indexOf(" ");
if (second == -1)
{
repeat = false;
XD = vowelFinder(a);
break;
}
else
{
XD = XD + vowelFinder(a.substring(first, second)); //30
}
first = second +1;
}while(repeat == true);
return XD;
}
private static boolean isVowel (char c)
{
if (c == 'a'|| c== 'e'|| c== 'i' || c == 'o' || c== 'u')
{
return true;
}
return false;
}
private static String vowelFinder(String s)
{
String nope = s;
for(int i = 0; i <= s.length(); i++)
{
if(isVowel(s.charAt(i)) == true)
{
nope = nope.substring(i) + "-"+nope.substring(0, i);`
return nope;
}
}
return nope;
}
}
Try this;
import java.util.Scanner;
public class PigLatin {
public static void main(String[] args) {
Scanner input = new Scanner( System.in );
String yourSentence="";
do {
String[] words;
System.out.print("Enter your words here: ");
yourSentence = input.nextLine();
words = yourSentence.split(" ");
for (String word : words) {
if (word.startsWith("a") || word.startsWith("e") || word.startsWith("i") || word.startsWith("o") || word.startsWith("u"))
System.out.print(word + "way ");
else if (word.startsWith("sh") || word.startsWith("ch") || word.startsWith("th"))
System.out.print(word.substring(2)+word.substring(0,2)+"ay ");
else
System.out.print(word.substring(1)+word.substring(0,1)+"ay ");
}
System.out.println();
} while(!yourSentence.equals("quit"));
}
}

Retrieving the two smallest inputs from an array in java

I'm taking an Intro to CS and one of the assignments asks for the 2 smallest numbers based off of user input. I've tried for about 3 days and just can't figure out why my code isn't working, and the more I work at it the more frustrated I get.
public class TwoSmallest {
public static void main(String[] args){
System.out.print("How many numbers will you be inputing? ");
int howManyNums = IO.readInt();
int[] arrayScores = new int[howManyNums];
for(int j = 0;j < howManyNums;j++){
System.out.print("Inuput number "+(j+1)+": ");
arrayScores[j]=IO.readInt();
int tinyNum1 = arrayScores[0];
int tinyNum2 = arrayScores[1];
for(int m = 0;tinyNum1 < arrayScores[m];m++){
//if (tinyNum1 < m) {
tinyNum1 = arrayScores[m];
}
for (int n = 1;tinyNum2 < arrayScores[n];n++){
//if (tinyNum2 < n) {
tinyNum2 = arrayScores[n];
}
if (tinyNum2 < tinyNum1){
int swapTinyNum1 = tinyNum1;
tinyNum2 = swapTinyNum1;
}
System.out.println("Smallest number: "+tinyNum1);
System.out.println("Followed by: "+tinyNum2);
}
We use the IO.readInt() for user input which I use to define the size of the array. I use it again at arrayScores[j]=IO.readInt(); to load the array. It kind of works when the user inputs the lower numbers first, but not when the higher numbers are input first. I think I'm having problems with retrieving the value at the designated index. It's probably a mess, but if anyone can help me out, it would definitely be appreciated. And here is the IO module we use, if this helps. I'm going to continue my endless battle at making this thing work..
import java.io.*;
public class IO
{
private static BufferedReader kb =
new BufferedReader(new InputStreamReader(System.in));
private static BufferedReader fio = null;
public static boolean openFile(String filename){
try{
fio = new BufferedReader(new FileReader(filename));
return true;
}catch (IOException e){ return false;}
}
public static String readLine(){
if (fio == null)
return null;
try{
return fio.readLine();
}catch(IOException e){ return null;}
}
public static String readString()
{
while (true) {
try {
return kb.readLine();
} catch (IOException e) {
// should never happen
}
}
}
public static int readInt()
{
while (true) {
try {
String s = kb.readLine();
return Integer.parseInt(s);
} catch (NumberFormatException e) {
System.out.print("That is not an integer. Enter again: ");
} catch (IOException e) {
// should never happen
}
}
}
public static double readDouble()
{
while (true) {
try {
String s = kb.readLine();
return Double.parseDouble(s);
} catch (NumberFormatException e) {
System.out.print("That is not a number. Enter again: ");
} catch (IOException e) {
// should never happen
}
}
}
public static char readChar()
{
String s = null;
try {
s = kb.readLine();
} catch (IOException e) {
// should never happen
}
while (s.length() != 1) {
System.out.print("That is not a single character. Enter again: ");
try {
s = kb.readLine();
} catch (IOException e) {
// should never happen
}
}
return s.charAt(0);
}
public static boolean readBoolean()
{
String s = null;
while (true) {
try {
s = kb.readLine();
} catch (IOException e) {
// should never happen
}
if (s.equalsIgnoreCase("yes") ||
s.equalsIgnoreCase("y") ||
s.equalsIgnoreCase("true") ||
s.equalsIgnoreCase("t")) {
return true;
} else if (s.equalsIgnoreCase("no") ||
s.equalsIgnoreCase("n") ||
s.equalsIgnoreCase("false") ||
s.equalsIgnoreCase("f")) {
return false;
} else {
System.out.print("Enter \"yes\" or \"no\": ");
}
}
}
public static void outputStringAnswer(String s)
{
if (s != null) {
System.out.println("RESULT: \"" + s + "\"");
} else {
System.out.println("RESULT: null");
}
}
public static void outputIntAnswer(int i)
{
System.out.println("RESULT: " + i);
}
public static void outputDoubleAnswer(double d)
{
System.out.println("RESULT: " + d);
}
public static void outputCharAnswer(char c)
{
System.out.println("RESULT: '" + c + "'");
}
public static void outputBooleanAnswer(boolean b)
{
System.out.println("RESULT: " + b);
}
public static void reportBadInput()
{
System.out.println("User entered bad input.");
}
}
To find the two smallest number:
int[] numbers = {}; // whatever.
int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] < min1) {
min2 = min1;
min1 = numbers[i];
} else if (numbers[i] < min2) {
min2 = numbers[i];
}
}

Error in String/character uppercase/lowercase conversion with loop

I have been doing an assignment, and I'm stuck. If I enter the letters: ahb, it prints only the last letter b not the whole thing:
public void run()
{
String value;
while (true) {
try {
value = (String) conB.remove();
if(value != null) { {
for(int i=0; i < value.length(); i++) {
if(Character.isDigit(value.charAt(i))) {
int x = Integer.parseInt(value);
bConWin.setData(" "+(x*2));
}
if(Character.isLowerCase(value.charAt(i))) {
char x = value.toUpperCase().charAt(i);
//changed.append(Character.toUpperCase(x));
bConWin.setData(" " +x);
}
if(Character.isUpperCase(value.charAt(i))) {
char x = value.toLowerCase().charAt(i);
bConWin.setData(" "+x);
}
}
}
}
}
}
You are only ever assigning one character as bConWin's data. Here's a fix as well as some tidying:
public static void main(String args[]) {
String value = "HaaaOppSaN";
if(value != null) {
StringBuilder newValue = new StringBuilder();
for(int i = 0; i < value.length(); i++) {
char x = value.charAt(i);
if(Character.isLowerCase(x)) {
x = Character.toUpperCase(x);
} else {
x = Character.toLowerCase(x);
}
newValue.append("" + x);
}
bConWin.setData(newValue.toString());
}
}
The outer endless loop is not needed. The try without a catch block as well.
Take a look at this:
public static void main(String[] args) {
String switched = switchCharacterCase("Hello World!");
bConWin.setData(switched);
System.out.println(switched);
}
public static String switchCharacterCase(final String input) {
StringBuilder switched = new StringBuilder();
if(input != null) { // nothing to do here, return switched
for(int i = 0; i < input.length(); i++) {
Character c = input.charAt(i);
if(Character.isLowerCase(c)) {
c = Character.toUpperCase(c);
} else {
c = Character.toLowerCase(c);
}
switched.append(c);
}
}
return switched.toString();
}

How to well adjust a loop in Java?

I am currently writing a little program to ask a PinCode to a user and return ":)" if the Pin is good or ":(" if the Pin is wrong.
My code is made of one java file and one text file.
This is the code :
import java.io.*;
import java.util.*;
public class Main {
static public boolean readPinsData(File dataFile, ArrayList<Integer> data) {
boolean err = false;
try {
Scanner scanner = new Scanner(dataFile);
String line;
while (scanner.hasNext()) {
line = scanner.nextLine();
try {
data.add(Integer.parseInt(line));
} catch (NumberFormatException e) {
e.printStackTrace();
err = true;
}
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
err = true;
}
return err;
}
public static void main(String[] args) {
System.out.println("-----------------------");
System.out.println("MY APP");
System.out.println("-----------------------");
Console console = System.console();
int pinSize = 0;
int nbTry = 0;
do{
do{
char passwordArray[] = console.readPassword("Enter pin: ");
pinSize = passwordArray.length;
if(pinSize != 4){
System.out.println("Pin must be 4 digits");
} else {
System.out.println("Checking...");
}
ArrayList<Integer> pins = new ArrayList<Integer>();
readPinsData(new File("bdd.txt"), pins);
//System.out.println(pins);
//System.out.println(passwordArray);
String[] thePins = new String[pins.size()];
for (int i = 0; i < thePins.length; i++) {
thePins[i] = pins.get(i).toString();
}
String passEntered = String.valueOf(passwordArray);
for(int i = 0 ; i < thePins.length ; i++){
if(passEntered.equals(thePins[i]) && pinSize == 4){
System.out.println(":)");
} else if(!passEntered.equals(thePins[i]) && pinSize == 4){
nbTry++;
}
}
}while(nbTry < 3);
}while(pinSize != 4);
}
}
This is bdd.txt where all the good Pins are stored :
1111
2222
3333
4444
5555
6666
7777
8888
9999
Actually my problem is to limit the number of try to 3 tries. I need to explain:
--> the user has to enter a pin
--> either he enters a good 4 digits pin and it prints ":)" (and the app is done)
--> either he enters a wrong 4 digits pin and it prints ":(" and the nbTry must be ++.
In this case he has only 2 tries left
--> he also can enter a 1-digit pin or 2-digits pin or 3-digits pin ... and in this case nbTry is not affected, he just have to re-enter a 4 digits pin.
I can not find out how to do with the nbTry left part.. Any ideas ?
Do you want him to be able to enter a 4 digit pin only or do you want him to be able to enter any length of pin?
Edit:
Reading your main I saw that you have two 'do...while`. If you change the order of them It should work. I can't test it atm because I'm on mobile bit try it like this:
do {
do {
....
} while (pinSize != 4);
} while (nbTry < 3);
Edit2:
boolean loginCorrdect = false;
for (int i = 0; i < thePins.length; i++) {
if (passEntered.equals(thePins[i]) && pinSize == 4) {
System.out.println(":)");
booleanCorrect = true;
break;
} else if (!passEntered.equals(thePins[i]) && pinSize == 4) {
System.out.println(":(");
}
}
if(!booleanCorrect && pinSize == 4){
nbTry++;
}
Hope you got it as its hard to type on mobile.
The full main code:
public static void main(String[] args) {
System.out.println("-----------------------");
System.out.println("MY APP");
System.out.println("-----------------------");
Console console = System.console();
int pinSize = 0;
int nbTry = 0;
boolean authenticated = false;
do {
do {
char passwordArray[] = console.readPassword("Enter pin: ");
pinSize = passwordArray.length();
if (pinSize != 4) {
System.out.println("Pin must be 4 digits");
} else {
System.out.println("Checking...");
}
ArrayList<Integer> pins = new ArrayList<Integer>();
readPinsData(new File("bdd.txt"), pins);
// System.out.println(pins);
// System.out.println(passwordArray);
String[] thePins = new String[pins.size()];
for (int i = 0; i < thePins.length; i++) {
thePins[i] = pins.get(i).toString();
}
String passEntered = String.valueOf(passwordArray);
for (int i = 0; i < thePins.length; i++) {
if (passEntered.equals(thePins[i]) && pinSize == 4) {
System.out.println(":)");
authenticated = true;
break;
}
}
} while (pinSize != 4);
if (!authenticated && pinSize == 4) {
System.out.println(":(");
nbTry++;
}
} while (nbTry < 3 && !authenticated);
}
If I understand your question, you can do it like so (and you should close() your Scanner when done) -
static public boolean readPinsData(File dataFile, ArrayList<Integer> data) {
boolean err = false;
Scanner scanner = null; // so we can close the Scanner.
try {
scanner = new Scanner(dataFile);
String line;
while (scanner.hasNext()) {
line = scanner.nextLine();
try {
data.add(Integer.parseInt(line));
} catch (NumberFormatException e) {
e.printStackTrace();
err = true;
}
// Limit it to 3 attempts. Set err on 3rd.
if (data.size() >= 3) {
err = true;
break;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
err = true;
} finally {
if (scanner != null) { // Close the Scanner.
scanner.close();
}
}
return err;
}
What helps is to have a top-down refinement of your control flow / logic.
As this reeks a bit of home work, just an idea:
Set<String> pins = readPINs();
boolean authenticated = false;
for (int attempt = 0; attempt < 3; ++attempt) {
String pin = askForPIN();
if (!isSyntacticalValidPIN(pin)) {
giveError();
break;
} else if (pins.contains{pin)) {
authenticated = true;
break;
}
}
if (authenticated) {
offerMenu();
}

Categories

Resources