I have written the following method to validate an input String and output it as an int array. The method works completely as I need it to but I would like to add some extra validation to it so that it only allows integers and commas in the input so there are no errors.
An example correct input would be:
"7,23,62,8,1130"
The method is:
public static int[] validator (String [] check) {
int [] out = new int[5];
try
{
if (0 < Integer.parseInt(check[0]) && Integer.parseInt(check[0]) < 100)
{
out[0] = Integer.parseInt(check[0]);
}
else
{
throw new InvalidMessageException();
}
}
catch (InvalidMessageException ex)
{
System.err.println("Invalid instruction message");
return null;
}
try
{
if (0 < Integer.parseInt(check[1]))
{
out[1] = Integer.parseInt(check[1]);
}
else
{
throw new InvalidMessageException();
}
}
catch (InvalidMessageException ex)
{
System.err.println("Invalid instruction message");
return null;
}
try
{
if(0 < Integer.parseInt(check[2]))
{
out[2] = Integer.parseInt(check[2]);
}
else
{
throw new InvalidMessageException();
}
}
catch (InvalidMessageException ex)
{
System.err.println("Invalid instruction message");
return null;
}
try
{
if (0 <= Integer.parseInt(check[3]) && Integer.parseInt(check[3]) < 256)
{
out[3] = Integer.parseInt(check[3]);
}
else
{
throw new InvalidMessageException();
}
}
catch (InvalidMessageException ex)
{
System.err.println("Invalid instruction message");
return null;
}
try
{
if(0 < Integer.parseInt(check[4]))
{
out[4] = Integer.parseInt(check[4]);
}
else
{
throw new InvalidMessageException();
}
}
catch (InvalidMessageException ex)
{
System.err.println("Invalid instruction message");
return null;
}
return out;
}
I have considered doing something like:
inputText = inputText.replace(".", "");
inputText = inputText.replace(":", "");
inputText = inputText.replace(";", "");
inputText = inputText.replace("\"", "");
etc... but it does not seem a particularly great solution. If anyone has a better idea, please let me know. Thanks very much for any help!
I'd say something like this should replace your method, without having read your code, just your requirements:
String input = "7,23,62,8,1130";
if (input.matches("(?:\\d+(?:,|$))+")) {
int[] result = Arrays.stream(input.split(",")).mapToInt(Integer::parseInt).toArray();
} else {
throw new InvalidMessageException("");
}
You can use a regex expression to validate your input:
[0-9]+(,[0-9]+)*,?
Check it with the String matches(regex) method as:
if (yourString.matches("[0-9]+(,[0-9]+)*,?")) {
}
This is exactly what regular expressions are for:
return inputText.matches("\\d+(,\\d+)*");
Related
So, I'm trying to create a function (If not pretty) IRC client using no libraries, written in Java. I've gotten almost everything working, the only problem is that I'm currently getting user input using System.in. And if someone else in the channel sends a message while I'm in the middle of typing, it cuts off what I currently have, and I need to guess where I am in the string. I want to know if there's a way to separate user input from the output of the program, so that this doesn't happen. This is the code in question:
new Thread(() -> {
while(connected[0]) {
String output = sc.nextLine();
if(!output.startsWith("~") && !output.startsWith("/")) {
try {
writeToSocket("PRIVMSG " + focused[0] + " " + output);
} catch (IOException e) {
e.printStackTrace();
}
}
if(output.substring(1).toLowerCase().startsWith("quit")) {
String[] split = output.substring(5).split(" ");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < split.length; i++) {
if(i == 0) {
sb.append(split[i]);
}
sb.append(" ").append(split[i]);
}
try {
writeToSocket("QUIT " + sb.toString());
connected[0] = false;
} catch (IOException e) {
e.printStackTrace();
}
}else if(output.substring(1).toLowerCase().startsWith("focus")) {
String get = output.substring(7);
if(!channels.contains(get)) {
print("Not connected to channel");
}else {
try {
writeToSocket("PART " + focused[0]);
writeToSocket("JOIN " + get);
} catch (IOException e) {
e.printStackTrace();
}
focused[0] = get;
}
}else if(output.substring(1).toLowerCase().startsWith("join")) {
String get = output.substring(6);
channels.add(get);
}
if(output.startsWith("/") && output.substring(1).toLowerCase().startsWith("msg")) {
String[] split = output.substring(5).split(" ");
String username = split[0];
StringBuilder msg = new StringBuilder();
for(int i = 1; i < split.length; i++) {
if(i == 1) {
msg.append(split[i]);
continue;
}
msg.append(" ").append(split[i]);
}
try {
writeToSocket("PRIVMSG " + username + " " + msg.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
If work.length is 4 ,
I have to check the AResult in for loop
If 4 AResult all are true ,set result.setstatus("success");
or result.setstatus("fail");
What can I do ??
for(int i = 0;i < work.length;i++){
if(!work[i].contains("#")){
CommandLineInterface CLI = new CommandLineInterface();
String IP = null;
boolean AResult;
try {
AResult = CLI.Setting(work[i],"start"); //true or false
} catch (JSchException | InterruptedException e) {
e.printStackTrace();
}
}
}
//result.setstatus("success"); //all true
//result.setstatus("fail");
Add a counter. Increment it when your condition is true. Check the value of the counter after your loop. Something like
int counter = 0;
for(int i = 0;i < work.length;i++){
if(!work[i].contains("#")){
CommandLineInterface CLI = new CommandLineInterface();
String IP = null;
boolean AResult;
try {
AResult = CLI.Setting(work[i],"start");
if (AResult) {
counter++;
}
} catch (JSchException | InterruptedException e) {
e.printStackTrace();
}
}
}
if (work.length == 4 && counter == 4) {
result.setstatus("success");
} else {
result.setstatus("fail");
}
You could optimize the above (and reduce the code size) with something like
int counter = 0;
if (work.length == 4) { // <-- check the length first
for (int i = 0; i < work.length; i++) {
if (!work[i].contains("#")) {
CommandLineInterface CLI = new CommandLineInterface();
try {
if (CLI.Setting(work[i], "start")) {
counter++; // <-- increment the counter.
} else {
break; // <-- break on any fale.
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
result.setstatus(counter == 4 ? "success" : "fail"); // <-- setstatus
try this, you really don't need to iterate the loop till end when a false condition is encountered in between
//initially set success
result.setstatus("success");
for(int i = 0;i < work.length;i++){
if(!work[i].contains("#")){
CommandLineInterface CLI = new CommandLineInterface();
String IP = null;
try {
if(CLI.Setting(work[i],"start"))
{
result.setstatus("fail");
//no need to iterate further
break;
}
} catch (JSchException | InterruptedException e) {
e.printStackTrace();
}
}
}
You can also try the following code
boolean statusFlag = true;
for(int i = 0;i < work.length;i++){
if(!work[i].contains("#")){
CommandLineInterface CLI = new CommandLineInterface();
String IP = null;
boolean AResult;
try {
AResult = CLI.Setting(work[i],"start"); //true or false
if(!AResult){
statusFlag = false;
}
} catch (JSchException | InterruptedException e) {
e.printStackTrace();
}
}
}
if(statusFlag){
result.setstatus("success");
}else{
result.setstatus("fail");
}
}
So my code looks like this:
try {
t.delete("word");
result = t.getRootItem().getWord().equals("humpty");
} catch (Exception e) {
result = false;
}
The problem is my compiler keeps saying I have a catch without a previous try but I do have a previous try so what's wrong? Here's my entire main method (I can also post the entire class if you want:
public static void main(String args[]) {
BSTRefBased t;
AbstractBinaryTree tt;
int i;
boolean result;
String message;
message = "Test 1: inserting 'word0' -- ";
t = new BSTRefBased();
try {
t.insert("word0");
result = t.getRootItem().getWord().equals("word0");
} catch (Exception e) {
result = false;
}
System.out.println(message + (result ? "passed" : "FAILED"));
message = "Test 2: inserting 'word1', 'word2', 'word3' -- ";
t = new BSTRefBased();
try {
t.insert("word1");
t.insert("word2");
t.insert("word3");
result = t.getRootItem().getWord().equals("word1");
tt = t.detachLeftSubtree();
result &= tt.getRootItem().getWord().equals("word2");
tt = t.detachRightSubtree();
result &= tt.getRootItem().getWord().equals("word3");
} catch (Exception e) {
result = false;
}
System.out.println(message + (result ? "passed" : "FAILED"));
message = "Test 3: deleting 'word3'";
t = new BSTRefBased
try {
t.delete("word3");
result = t.getRootItem().getWord().equals("word3");
} catch (Exception e) {
result = false;
}
System.out.println(message + (result ? "passed" : "FAILED"));
}
This line appears to be incorrect:
t = new BSTRefBased
There is no () for a constructor call, and there is no semicolon. It's immediately before the try, and those errors must be messing up the parser, such that it no longer recognizes the try. Try
t = new BSTRefBased(); // or a similar constructor call
here is a piece of code:
class Main {
public static void main(String[] args) {
try {
CLI.parse (args, new String[0]);
InputStream inputStream = args.length == 0 ?
System.in : new java.io.FileInputStream(CLI.infile);
ANTLRInputStream antlrIOS = new ANTLRInputStream(inputStream);
if (CLI.target == CLI.SCAN || CLI.target == CLI.DEFAULT)
{
DecafScanner lexer = new DecafScanner(antlrIOS);
Token token;
boolean done = false;
while (!done)
{
try
{
for (token=lexer.nextToken();
token.getType()!=Token.EOF; token=lexer.nextToken())
{
String type = "";
String text = token.getText();
switch (token.getType())
{
case DecafScanner.ID:
type = " CHARLITERAL";
break;
}
System.out.println (token.getLine() + type + " " + text);
}
done = true;
} catch(Exception e) {
// print the error:
System.out.println(CLI.infile+" "+e);
}
}
}
else if (CLI.target == CLI.PARSE)
{
DecafScanner lexer = new DecafScanner(antlrIOS);
CommonTokenStream tokens = new CommonTokenStream(lexer);
DecafParser parser = new DecafParser (tokens);
parser.program();
}
} catch(Exception e) {
// print the error:
System.out.println(CLI.infile+" "+e);
}
}
}
It prints out as it is but somehow it does not print the type out only the default value of it which is an empty string. How can I make it to print out from the switch statement?
Thanks!
Try debugging.
Try printing the value from within the switch section, to see if you ever get into it.
Try replacing the switch with a simple "==" to see if you ever get "token.getType() == DecafScanner.ID"
General suggestion - move the definition of "type" and "next" outside the loop to avoid recreating them again and again.
SOLVED IT
I've written a program that loads Strings after an equal sign, and has it count how many times its done this. After counting, I tell it to tell me how large the int is. The value I'm looking for is 3, and it tells me, 3. I then change it to an String, the value stays three. Then, I put it into an 4d array, and It tells me the value is 2. What happened?
The Code:
int times=0;
else if (list.equals("Weapon")) {//If the word weapon is before the =
weapon = value; //take the string after the = and put it into String weapon
troopStats[times][1][weaponTimes][0] = weapon;
weaponTimes++;
System.out.println(weaponTimes+"weapontimes"+times);
}
weaponTimesStr = Integer.toString(weaponTimes);
System.out.println(weaponTimesStr+"string");
troopStats[times][1][0][1] = weaponTimesStr;
System.out.println(troopStats[times][1][0][1]+"InArray");
times++
//loops
The Output:
3weapontimes //Counted the equals sign 3 times, Note that this is from the part of the
omitted code
3string // Changed the integer to a string and got 3
2InArray // Put it into an array, and got 2 back
What Is going on?
(I know that I could just add 1 to the value, but I want to use this code for a unknown number of things later on)
To help, I've posted the entire code:
public class TroopLoader {
static String[][][][] troopStats;
static int times = 0;
static int weaponTimes = 0;
static int armorTimes = 0;
static int animalTimes = 0;
static String weaponTimesStr;
static String armorTimesStr;
static String animalTimesStr;
static String troop;
static String weapon;
static String armor;
static String animal;
static String speed;
static int total = 0;
/*
* [][][]
*
* [total number of troops (total)]
*
* [stats] 0= name 1= weapon 2= armor 3= animal 4= speed
*
* [different things within stat]
*/
public void readTroop() {
File file = new File("resources/objects/troops.txt");
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String text = null;
// repeat until all lines is read
while ((text = reader.readLine()) != null) {
StringTokenizer troops = new StringTokenizer(text, "=");
if (troops.countTokens() == 2) {
String list = troops.nextToken();
if (list.equals("Troop")) {
total++;
}
else {
}
} else {
}
}
troopStats = new String[total][5][10][2];
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
File file2 = new File("resources/objects/troops.txt");
BufferedReader reader2 = null;
try {
reader2 = new BufferedReader(new FileReader(file2));
String text = null;
// repeat until all lines is read
while ((text = reader2.readLine()) != null) {
StringTokenizer troops = new StringTokenizer(text, "=");
if (troops.countTokens() == 2) {
String list = troops.nextToken();
String value = troops.nextToken();
if (list.equals("Troop")) {
troop = value;
troopStats[times][0][0][0] = troop;
}
else if (list.equals("Weapon")) {
weapon = value;
troopStats[times][1][weaponTimes][0] = weapon;
weaponTimes++;
System.out.println(weaponTimes+"weapontimes"+times);
}
else if (list.equals("Armor")) {
armor = value;
troopStats[times][2][armorTimes][0] = armor;
armorTimes++;
}
else if (list.equals("Animal")) {
animal = value;
troopStats[times][3][animalTimes][0] = animal;
animalTimes++;
}
else if (list.equals("Speed")) {
speed = value;
troopStats[times][4][0][0] = speed;
}
else if (list.equals("Done")) {
weaponTimesStr = Integer.toString(weaponTimes);
System.out.println(weaponTimesStr+"string");
armorTimesStr = Integer.toString(armorTimes);
animalTimesStr = Integer.toString(animalTimes);
troopStats[times][1][0][1] = weaponTimesStr;
troopStats[times][1][0][1] = armorTimesStr;
troopStats[times][1][0][1] = animalTimesStr;
System.out.println(troopStats[times][1][0][1]+"InArray"+times);
times++;
troop = "";
weapon = "";
armor = "";
animal = "";
speed = "";
weaponTimes = 0;
armorTimes = 0;
animalTimes = 0;
}
else {
}
} else {
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try {
if (reader2 != null) {
reader2.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
In the earlier part of the code, I had the program store a value in the location on the array with the weaponTimes variable, not storing the weaponTimes variable. My mistake, sorry for wasting your time.
I wrote a SSCCE with what you posted and it prints what you would expect:
public static void main(String[] args) {
String[][][][] troopStats = new String[4][4][4][4];
int times = 2;
int weaponTimes = 3;
String weaponTimesStr = Integer.toString(weaponTimes);
System.out.println(weaponTimesStr + "string"); //prints 3string
troopStats[times][1][0][1] = weaponTimesStr;
System.out.println(troopStats[times][1][0][1] + "InArray"); //prints 3InArray
}
So the problem is most likely something/somewhere else.
The following:
public class Foo {
public static void main(String[] args) {
String[][][][] troopStats = new String[2][2][2][2];
String weaponTimesStr = Integer.toString(3);
System.out.println(weaponTimesStr+"string");
troopStats[0][1][0][1] = weaponTimesStr;
// You said in a comment that 'times' is equal to 0 in this case so have subbed that in
System.out.println(troopStats[0][1][0][1]+"InArray");
}
}
Gives me the expected output:
3string
3InArray
Sorry I've wasted your time, my mistake was because I stored values in the array using the values of weaponTimes, and not storing weaponTimes in the array.
troopStats[times][1][weaponTimes][0] = weapon;
That was the mistake.