I'm working on a server/client battleship game using sockets. Part of the project requires entry validation on the client side for entering tile locations. A user is supposed to enter a letter A-E and a number 1-5, and right now if you type in something invalid, it seems to freeze. Any help would be much appreciated, thanks in advance!
do{
System.out.println("------------------------------------------------------------------------------------------------");
System.out.println("Please type in a board position in the format of a letter followed by number, such as 'A1'. ");
Scanner sc = new Scanner(System.in);
String BoardChoice = sc.next();
if(BoardChoice.equals("A1" ) || BoardChoice.equals("B1" ) || BoardChoice.equals("C1" ) || BoardChoice.equals("D1" ) || BoardChoice.equals("E1" ) ||
BoardChoice.equals("A2" ) || BoardChoice.equals("B2" ) || BoardChoice.equals("C2" ) || BoardChoice.equals("D2" ) || BoardChoice.equals("E2" ) ||
BoardChoice.equals("A3" ) || BoardChoice.equals("B3" ) || BoardChoice.equals("C3" ) || BoardChoice.equals("D3" ) || BoardChoice.equals("E3" ) ||
BoardChoice.equals("A4" ) || BoardChoice.equals("B4" ) || BoardChoice.equals("C4" ) || BoardChoice.equals("D4" ) || BoardChoice.equals("E4" ) ||
BoardChoice.equals("A5" ) || BoardChoice.equals("B5" ) || BoardChoice.equals("C5" ) || BoardChoice.equals("D5" ) || BoardChoice.equals("E5" ))
{
flagtoo = false;
writer.writeUTF(BoardChoice);
}
else
{
System.out.println("Invalid Input Please re-enter!");
}
}while(flagtoo);
I would suggest you test each character separately by breaking them out with charAt, and please respect variable naming conventions. Something like
boolean valid = false;
String boardChoice = sc.nextLine(); // <-- not next
if (boardChoice.length() == 2) {
char col = boardChoice.charAt(0);
char row = boardChoice.charAt(1);
// The parenthesis here are just for clarity.
valid = ((col >= 'A' && col <= 'E') && (row >= '1' && row <= '5'));
}
My suggestion on the other hand will suggest to implement regex with a pattern that allows you to match 1st char alpha(no matter capitalization) followed by a number,
both in a range from a → e and 1 → 5
Scanner sc = new Scanner(System.in);
System.out.println("Please type in a ....y number, such as 'A1'. ");
do {
inp = sc.nextLine();
if (inp.matches("^[a-eA-E1-5]{0,2}")) {
inpArr[k++] = inp;
} else {
System.out.println("invalid input");
}
} while (k < numberOfElements);
System.out.println(Arrays.toString(inpArr));
Related
My code takes the users input and checks it for certain characters. If a unwanted character is found the programme asks for user input again however if I were to type the special character at the end of the text eg 'hello#' and then when im asked for the input again I type 'hello' I get a 'String index out of range: 5' error. How could I reinitialize the max variable so that when the input length changes max variable in the for loop changes too.
I tried assigning the max variable again but there was no luck.
Scanner keyboard= new Scanner(System.in);
System.out.println("Please enter text to encrypt:");
String input = keyboard.nextLine();
String text = input.toUpperCase();
char letter;
int max = text.length();
for(int i =0; i<max;i++){
letter = text.charAt(i);
while(letter=='#'||letter=='\''||letter==';'||letter==':'||letter==','||letter=='<'||letter=='.'||letter=='>'||letter=='/'||letter=='?'||letter=='#'||letter=='~'||letter=='['||letter==']'||letter=='{'||letter=='}'||letter=='='||letter=='+'||letter=='-'||letter=='_'||letter==')'||letter=='('||letter=='*'||letter=='&'||letter=='^'||letter=='%'||letter=='$'||letter=='$'||letter=='£'||letter=='"'||letter=='!'||letter=='`'||letter=='¬'||letter=='\\'||letter=='|'){
System.out.println("Invalid Input\nPlease enter text to encrypt:");
input = keyboard.nextLine();
text = input.toUpperCase();
letter = text.charAt(i);
i=-1;
}
max=text.length();
}
You should take the user input and validate it. If the input is invalid, you request it again. One way of doing this is something like:
Scanner keyboard = new Scanner(System.in);
boolean ok;
do {
ok = true;
System.out.println( "Please enter text to encrypt:" );
String text = keyboard.nextLine().toUpperCase();
for ( char letter : text.toCharArray() ) {
if ( letter=='#' || letter=='\'' || letter==';' || letter==':' ||
letter==',' || letter=='<' || letter=='.' || letter=='>' ||
letter=='/' || letter=='?' || letter=='#' || letter=='~' ||
letter=='[' || letter==']' || letter=='{' || letter=='}' ||
letter=='=' || letter=='+' || letter=='-' || letter=='_' ||
letter==')' || letter=='(' || letter=='*' || letter=='&' ||
letter=='^' || letter=='%' || letter=='$' || letter=='$' ||
letter=='£' || letter=='"' || letter=='!' || letter=='`' ||
letter=='¬' || letter=='\\' || letter=='|' ) {
ok = false;
break;
}
}
if ( !ok ) {
System.out.println("Invalid Input");
}
} while ( !ok );
I'm assuming that you want a String with only alphanumerical characters. If it's true, it could be much simpler:
Scanner keyboard = new Scanner(System.in);
boolean ok;
do {
System.out.println( "Please enter text to encrypt:" );
String text = keyboard.nextLine().toUpperCase();
// does text contains only characters from A to Z and/or 0 to 9,
// one or more times (+)
ok = text.matches( "[A-Z0-9]+" );
if ( !ok ) {
System.out.println("Invalid Input");
}
} while ( !ok );
It appears you just want legal alphaNumeric words. \\w+ matches those so try this.
Scanner keyboard = new Scanner(System.in);
while(true) {
System.out.println("Please enter text to encrypt:");
String input = keyboard.nextLine();
if (input.matches("\\w+")) {
break;
}
System.out.println("Invalid input");
}
I created a program that convert text to ASCII value and now when i press Y to try again and input a new string there will be a error that string is out of range etc.
I am new in this field, I will appreciate your help.
And here is the Error
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: index 17,length 17
at java.base/java.lang.String.checkIndex(String.java:3278)
at java.base/java.lang.AbstractStringBuilder.charAt(AbstractStringBuilder.java:307)
at java.base/java.lang.StringBuffer.charAt(StringBuffer.java:242)
at com.company.Main.main(Main.java:26)
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args)
{
boolean Flag; // The Boolean variable for the do while lopp
int n,l,j=0,m,i,ch;
char t;
StringBuffer data = new StringBuffer();
Scanner input = new Scanner(System.in);
do {
System.out.println("Enter any string and it will convert into numbers:- ");
data.append(input.nextLine());
l = data.length();
m = l;
System.out.println(l);
for (i = 0; i < m; i++) {
t = data.charAt(j);
n = (int) t;
System.out.print(n);
System.out.print(",");
j++;
}
data.delete(0, m-1);
System.out.println("\nDo you want to try again? Y/N");
ch = input.nextInt();
//Those are the condition for that the program should be run again or not
if (ch == 'Y' && ch == 'y')
Flag = true;
else if (ch == 'N' && ch == 'n')
Flag = true;
else
Flag = false;
}
while(Flag=true);
System.out.println("Thanks, Come Again");
}
}
while(Flag=true);
this doesn't check whether the value of Flag is true, it sets it to true, and thus automatically returns true.
What you want is:
while(Flag==true);
or,
while(Flag);
for short.
You may also want to read up about naming conventions.
As for your Exception:
Y is not an int, change your
ch = input.nextInt();
to
ch = input.nextLine().charAt(0);
this will solve the initial problem, but still might lead to false results with unexpected input (or lack there of)
int n,l,j=0,m,i,ch;
This declaration is invalid. If all of these values are supposed to be
0, the declaration should look like:
int n, l, j, m, i, ch = 0
Also your logic in the nextInput section is incorrect.
if (ch == 'Y' && ch == 'y')
Flag = true;
else if (ch == 'N' && ch == 'n')
Flag = true;
else
Flag = false;
Instead of the AND ( && ) this should be an OR ( || ). If it's 'Y' OR it's 'y'. It will likely never be both Y and y. This should be fixed as follows:
if (ch == 'Y' || ch == 'y') {
Flag = true;
} else if (ch == 'N' || ch == 'n') {
Flag = false;
}
Also, as mentioned by #Stultuske, you'll want to change your while condition to:
while (Flag == true)
One thing that's niggling at me here is that ch is an integer, but you're asking it if that value is 'Y, y, N, n' those are characters and not integers. I'm guessing that's why you got the 'Input_Mismatch_Exception'. Hope this helps.
Edit: Formatting
I am making a simple program that will take one word with "*" in the middle of the word ex: "Some*ing" and will take another string to replace it with the "*" in the first word. Like "th" -> output "Something".
Sample Run 1:
Enter the first String:
D*g
Enter the replacement String:
in
Ding
Simple enough. I made this program in IDEA (running Java 8) and it works alright (though I still need to add some minor stuff).
But in CodeRunner I have some problems. It says "java.lang.ArrayIndexOutOfBoundsException: 1". There is some mistake in my code and I have no idea where it is.
My code:
import java.util.Scanner;
import java.lang.Math;
import java.io.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the first String:");
//The inital String
String first = scan.nextLine();
System.out.println("Enter the replacement String:");
// SubString
String subs = scan.nextLine();
if (!(first.contains("!") || first.contains("#") || first.contains("#") || first.contains("$") || first.contains("%") || first.contains("^") || first.contains("&") || first.contains("(") || first.contains(")") || first.contains("+") || first.contains("-") || first.contains("_") || first.contains("~") || first.contains("`") || first.contains("\\") || first.contains("[") || first.contains("]") || first.contains("{") || first.contains("}") || first.contains(":") || first.contains(";") || first.contains("'") || first.contains("\"") || first.contains("/") || first.contains("?") || first.contains(".") || first.contains(">") || first.contains(",") || first.contains("<"))) {
if (first.contains("*") ) {
String parts[] = first.split("\\*");
String part1 = parts[0];
String part2 = parts[1];
String newString = part1 + subs + part2;
System.out.println(newString);
} else {
System.out.println("Error: no *");
}
} else {
System.out.println("Error: Incorrect characters");
}
}
}
The CodeRunner gives me that
Runtime Error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Main.main(Main.java:298)
at Ideone.assertRegex(Main.java:125)
at Ideone.test(Main.java:61)
at Ideone.main(Main.java:28)
Though code works at my IDE and we assume that it is possible to make so the code will work at the codeRunner
Thank you
Note: StringBuilder used only for demo
if (YOURSTRING.contains("*")) {
StringBuilder builder=new StringBuilder();
String parts[] = YOURSTRING.split("\\*");
for (int i = 0; i < parts.length; i++) {
builder.append(parts[i]);
}
System.out.println(builder.toString());
} else {
System.out.println("Error: no *");
}
use for loop instead of getting value statically from array
because if spit will done 1 time of non then this line
String part1 = parts[0];
String part2 = parts[1]; return ArrayIndexOutOfBoundsException because there is not a second element int array to get it, understood?
Thank's everybody who was helping me! I've learned about 10 new methods while solving this assignment until I found the resolution. That was a helpful experience. This assignment is done, I got an A for it (100%)! Thank you guys!
import java.util.Scanner;
public class AsmntFive {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the first String:");
String first = scan.nextLine();
System.out.println("Enter the replacement String:");
String subs = scan.nextLine();
if (!(first.contains("!") || first.contains("#") || first.contains("#") || first.contains("$") || first.contains("%") || first.contains("^") || first.contains("&") || first.contains("(") || first.contains(")") || first.contains("+") || first.contains("-") || first.contains("_") || first.contains("~") || first.contains("`") || first.contains("\\") || first.contains("[") || first.contains("]") || first.contains("{") || first.contains("}") || first.contains(":") || first.contains(";") || first.contains("'") || first.contains("\"") || first.contains("/") || first.contains("?") || first.contains(".") || first.contains(">") || first.contains(",") || first.contains("<"))) {
if (first.contains("*")) {
System.out.println(first.replace("*", subs));
} else {
System.out.println("Error: no *");
}
} else {
System.out.println("Error: Incorrect characters");
}
}
}
Im trying to turn a string taken from the user into Pig Latin. I cannot use any special classes, methods, or arrays. I can only use a Scanner to create a object to take the string from the user and .length and .charAt, in addition to any type of looping. (Also cannot use switch statements or the break keyword)
Here is an example of what my output is suppose to be:
Enter a line of text: this is a test.
Input : this is a line of text.
Output: his-tay is-way a-way ine-lay of-way ext-tay.
Here is my code, I can only get my code to work with one word and it must have a space at the end. Only one loop works at a time depending on the loop. Im not sure what to do if I get an entire String.
I know that when the user enters a space that signals a new word, and when they enter a period, that signals the ending.
I had a hard time understanding your code. (It looks like you are trying to do it two ways at once?) Regardless, I believe I was able to understand your question. Here is a compilable and runnable example:
import java.util.Scanner;
public class PigLatin
{
public static void main(String[] args)
{
System.out.print("Enter a line of text: ");
Scanner keyboard = new Scanner(System.in);
String text = keyboard.nextLine();
System.out.println("\nInput: " + text);
System.out.print("Output: ");
if (text != null && text.length() > 0)
{
int i = 0;
// this iterates through the whole string, stopping at a period or
// the end of the string, whichever is closer
while (i < text.length() && text.charAt(i) != '.')
{
// these three variables only exist in this code block,
// so they will be re-initialized to these values
// each time this while loop is executed
char first = '\0'; // don't worry about this, I just use this value as a default initializer
boolean isFirst = true;
boolean firstIsVowel = false;
// each iteration of this while loop should be a word, since it
// stops iterating when a space is encountered
while (i < text.length()
&& text.charAt(i) != ' '
&& text.charAt(i) != '.')
{
// this is the first letter in this word
if (isFirst)
{
first = text.charAt(i);
// deal with words starting in vowels
if (first == 'a' || first == 'A' || first == 'e' || first == 'E'
|| first == 'i' || first == 'I' || first == 'o' || first == 'O'
|| first == 'u' || first == 'U')
{
System.out.print(first);
firstIsVowel = true;
}
// make sure we don't read another character as the first
// character in this word
isFirst = false;
}
else
{
System.out.print(text.charAt(i));
}
i++;
}
if (firstIsVowel)
{
System.out.print("-tay ");
}
else if (first != '\0')
{
System.out.print("-" + first + "ay ");
}
i++;
}
System.out.print('\n'); //for clean otuput
}
}
}
There are a few comments in there that might help guide you through my logic. This is almost definitely not the most efficient way to do this (even with your limitations), as I only whipped it up as a example of the type of logic you could use.
You could break it up into words, then process the current word when you hit a space or period:
System.out.print("Enter a line of text: ");
Scanner keyboard = new Scanner(System.in);
String text = keyboard.nextLine();
System.out.println("\nInput: " + text);
System.out.print("Output: ");
String curWord = "";
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == ' ' || text.charAt(i) == '.') {
if (curWord.charAt(0) == 'a' || curWord.charAt(0) == 'e' ||
curWord.charAt(0) == 'i' || curWord.charAt(0) == 'o' ||
curWord.charAt(0) == 'u') {
System.out.print(curWord + "-way ");
} else {
for (int j = 1; j < curWord.length(); j++) {
System.out.print(curWord.charAt(j);
}
System.out.print("-" + curWord.charAt(0) + "ay ");
//System.out.print(curWord.substring(1)+"-"+curWord.charAt(0)+"ay ");
}
curWord = "";
} else {
curWord += text.charAt(i);
}
}
I am trying to calculate an arithmetic expression, which is entered as a string (for example, ( 5+4*5-1/8 ), which will give the result 3). I enter an expression and convert it into an array. First; the result will start with the first element and it will change in the loop. But the problem is operator precedence. How can I use the operator presedence in a loop? Here is my code:
import java.util.Scanner;
public class HesapMakinesi {
private char value[];
private int count;
private Scanner str = new Scanner(System.in);
private String process;
HesapMakinesi() {
System.out.print("Enter the process ");
process = str.next();
//System.out.println(islem);
Initializer(process);
}
private void Initializer(String process) {
count = process.toCharArray().length;
value = new char [count];
int i;
System.arraycopy(process.toCharArray(), 0, value, 0, count);
//System.out.println(value);
if(value[0]=='-' || value[0]=='+' || value[0]=='/' || value[0]=='*' || // A process cannot start with an operator
value[count-1]=='-' || value[count-1]=='+' || value[count-1]=='/' || value[count-1]=='*') {
System.out.println("You have entered a wrong process.Please enter again!!!");
System.out.print("Enter the process: ");
process = str.next();
Initializer(process);
}
for(i=0; i<count; i++) { // A process cannot include a character except operators
if( value[i]!='+' && value[i]!='-' && value[i]!='*' && value[i]!='/' && value[i]!='(' && value[i]!=')' && !Character.isDigit(value[i]) ) {
System.out.println("You have entered a wrong process.Please enter again!!!");
System.out.print("Enter the process: ");
process = str.next();
Initializer(process);
}
}
for(i=0; i<count-1; i++) { // A process cannot have operators sequantially
if( !Character.isDigit(value[i]) && !Character.isDigit(value[i+1]) ) {
if( (value[i] == '+' && value[i+1] == '+' ) || (value[i] == '+' && value[i+1] == '-' ) || (value[i] == '+' && value[i+1] == '*' ) ||
(value[i] == '+' && value[i+1] == '/' ) ) {
System.out.println("You have entered a wrong process.Please enter again!!!");
System.out.print("Enter the process: ");
process = str.next();
Initializer(process);
}
else if( (value[i] == '-' && value[i+1] == '+' ) || (value[i] == '-' && value[i+1] == '-' ) || (value[i] == '-' && value[i+1] == '*' ) ||
(value[i] == '-' && value[i+1] == '/' ) ) {
System.out.println("You have entered a wrong process.Please enter again!!!");
System.out.print("Enter the process: ");
process = str.next();
Initializer(process);
}
else if( (value[i] == '*' && value[i+1] == '+' ) || (value[i] == '*' && value[i+1] == '-' ) || (value[i] == '*' && value[i+1] == '*' ) ||
(value[i] == '*' && value[i+1] == '/' ) ) {
System.out.println("You have entered a wrong process.Please enter again!!!");
System.out.print("Enter the process: ");
process = str.next();
Initializer(process);
}
else if( (value[i] == '/' && value[i+1] == '+' ) || (value[i] == '/' && value[i+1] == '-' ) || (value[i] == '/' && value[i+1] == '*' ) ||
(value[i] == '/' && value[i+1] == '/' ) ) {
System.out.println("You have entered a wrong process.Please enter again!!!");
System.out.print("Enter the process: ");
process = str.next();
Initializer(process);
}
}
}
//sCount();
}
/*private void Count(){
double result,temp;
int i;
for(i=0; i<count; i++) {
if( value[i]!= )
}
}*/
}
That's not how you do it. You need to parse the expression before evaluating it. I suggest you to read the Shunting-yard algorithm.
Following on from my comment... If you're dealing with a simple expression where you can only have numbers and signs +-/* then you can have a simple approach:
split your expression by lowest precedence operators first (+-) remembering the signs.
Compute each piece - as now the precedence isn't important, since everything is of the same level
sum those computed pieces taking into account the sign of the piece from step 1.
In your example, you'll end up with something like this:
(Split by +-) three pieces: (1) 5; (2) 4*5 with sign +; (3) 1/8 with sign -
Compute each of the three pieces: (1) 5; (2) 20; (3) 0.125
Sum the three pieces with their respective signs: 5+20-0.125 = 24.875