I am trying to write a basic program in Java that checks if an IP address is valid. I am trying to use no external classes other than the Scanner class and also no regular expressions.
My code, available at this gisttakes in 4 integers as input, one for each octet. I also have this codewhich is a little more readable than the first but is longer.
My question is, is there any other way to implement this idea in significantly fewer lines, and if so, how would I accomplish this?
While this code segment is a bit verbose, it is simple, self-descriptive, and has proven to be tight.
private static boolean isIPAddressValid(String ip) {
boolean result = true;
int i = 0;
int [] val = new int[4];
if ((ip == null) || (ip.trim().length() == 0))
{
//null ip address entered
result = false;
}
else
{
if (!(ip.contains(".")))
{
//no '.' found
result = false;
}
else
{
String [] parts = ip.split("\\.");
if (!(parts.length == 4))
{
//not 4 quadrants
result = false;
}
else
{
for (String s : parts) {
try {
val[i] = Integer.parseInt(s);
if ((val[i] < 0) || (val[i] > 255))
{
//this quadrant's value exceeds limits
result = false;
}
i++;
} catch (Exception e) {
//failed to parse quadrant to an integer");
result = false;
}
}
}
}
}
return result;
}
only some minor enhancements (i think your code looks very good - my opinio so far) it is clearly to read and all work blocks are properly to understand....
boolean isFailed = false;
if (first < 0 || first > 255) {
System.out.println("Octet 1 is invalid");
isFailed = true;
}
if (second < 0 || second > 255) {
System.out.println("Octet 2 is invalid");
isFailed = true;
}
if (third < 0 || third > 255) {
System.out.println("Octet 3 is invalid");
isFailed = true;
}
if (fourth < 0 || fourth > 255) {
System.out.println("Octet 4 is invalid");
isFailed = true;
}
if (!isFailed){
System.out.println("IP Address: " + first + "." + second + "." + third + "." + fourth);
}
so i simply invert the order of printing - that saves you only that big check before...
your approach was to can check each octet...
you can simply do this 4 times or write a method for it:
private static boolean check(int octet, int index){
if (0xFF & octet < 256) return true;
System.out.println("Octet "+index+" is invalid";
return false;
}
and use this method in your main method
if (check(first,0) && check (second, 2) && check (third, 3) && check(fourth, 4) ){
System.out.println("your ip is valid");
}
note - this only reveals the first invalid octet - if you want to check all you need another boolean
boolean result = check(first,0) &&
check (second, 2) &&
check (third, 3) &&
check(fourth, 4); //reveals all errors
a totally different approach would be to use http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#getByName%28java.lang.String%29
try{
/*InetAdress adress =*/ InetAdress.
getByName(""+first+"."+second+"."+third+"."+forth)
System.out.println("your ip is valid");
}catch (UnknownHostException e){
//TODO represent that error message into a nice expression
System.out.println("your ip is invalid");
}
but this as well doesn't provide information about that octet which is invalid...
(by the way - what is wrong with your code? it's fine, really!)
I was just bored and wrote this regexp
public static boolean isValid(String ip) {
boolean isvalid;
isvalid = ip.matches(
"(([0-9]|[0-9]{0,2}|1[0-9]*{0,2}|2[0-5][0-5]|0{0,3}).){3}" +
"([0-9]|[0-9]{0,2}|1[0-9]*{0,2}|2[0-5][0-5]|0{0,3})"
);
return isvalid;
}
And it was tested on the following dataset:
String[] ips = {
"0.0.0.0",
"0.111.222.0",
"0.0.0.000",
"0.00.0.000",
"1.1.1.1",
"2.2.2.2",
"12.13.14.15",
"29.29.29.29",
"99.99.000.1",
"111.102.144.190",
"255.255.199.199",
"266.255.255.255", //inv
"255.265.255.255", //inv
"255.255.258.255", //inv
"255.255.255.259", //inv
"299.100.110.255" //inv
};
for (String s : ips) {
if (isValid(s) == false) {
System.err.println(s + " is invalid");
}
}
Related
This should be easily and quickly answerable. It is about throwing exceptions, and I have very little understanding of that topic (because I am a novice).
The code below represents of the most important methods from my simple 'maze game' program. In this method, I am (obviously) enumerating the possible user keyboard commands and giving the instructions for their execution by calling other sub-methods. Evidently, I want all keyboard inputs that aren't "help", "status" ... "down" to result in the error message at the bottom of the method.
I know that what I've got here is dumb and makes no sense, but that's because I literally have no idea what I'm doing when it comes to throwing exceptions, and I am too lazy to do any serious reading. So I would love if someone could just tell me how to write what I want to write here.
public static void performAction(String action) throws IllegalArgumentException {
if (action.equalsIgnoreCase("help")) {
printHelp(); }
else if (action.equalsIgnoreCase("status")) {
printStatus(); }
else if (action.equalsIgnoreCase("board")) {
printBoard(); }
else if (((action.charAt(0) == 'S') || (action.charAt(0) == 's')) && ((action.charAt(1) == 'a') || (action.charAt(1) == 'A')) && ((action.charAt(2) == 'v') || (action.charAt(2) == 'V')) &&
((action.charAt(3) == 'e') || (action.charAt(3) == 'E')) && (action.charAt(4) == ' ')) {
String [] parts = action.split(" ");
String saveCommand = parts[0];
String fileName = parts[1];
try { saveGame(fileName); }
catch(IOException e) {
System.err.printf("Error: Could not save the current game configuration to \'%s\'.", fileName);
return; } }
else if (action.equalsIgnoreCase("left")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo((a - 1), b); }
else if (action.equalsIgnoreCase("right")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo((a + 1), b); }
else if (action.equalsIgnoreCase("up")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo(a, (b - 1)); }
else if (action.equalsIgnoreCase("down")) {
int a = getCurrentXPosition();
int b = getCurrentYPosition();
moveTo(a, (b + 1)); }
else {
try {}
catch (IllegalArgumentException e) {
System.err.printf("Error: Could not find command \'%s\'.\nTo find the list of valid commands, please type 'help'. \n", action); }
}
}
else {
System.err.printf("Error: Could not find command \'%s\'.\nTo find the list of valid commands, please type 'help'. \n", action);
throw IllegalArgumentException ;
}
This will log the message and then exit the method by throwing IllegalArgumentException exception
There is something wrong with my code as one the testcase in my assignment is coming out wrong, giving me runtime error when I submit the code online. That testcase could be any String. I believe that everything is fine with the code as I have checked it manually for many testcases.
HERE IS THE CODE
public static boolean isStringPalindrome(String input) {
if(input.length()==0 || input.length()==1)
return true;
int first = 0;
int last = input.length()-1;
if(input.charAt(first) != input.charAt(last))
return false;
String str="";
for(int i=first+1;i<last;i++){
str = str+input.charAt(i);
}
boolean sa = isStringPalindrome(str);
return sa;
}
Sample Input
racecar
Output
true
Sample Input
pablo
Output
false
Your code appears to be overly complicated for recursively testing if the String is a palindrome. Something like,
public static boolean isStringPalindrome(String input) {
if (input == null) {
return false;
} else if (input.isEmpty() || input.length() == 1) {
return true;
}
int len = input.length() - 1;
return input.charAt(0) == input.charAt(len) //
&& isStringPalindrome(input.substring(1, len));
}
Is recursive without embedding a for loop. Because if you can do that, you should do something like
public static boolean isStringPalindrome(String input) {
if (input == null) {
return false;
} else if (input.isEmpty() || input.length() == 1) {
return true;
}
int len = input.length();
for (int i = 0; i <= len / 2; i++) {
if (input.charAt(i) != input.charAt(len - 1 - i)) {
return false;
}
}
return true;
}
A simpler way to check for palindrome can be:
public static boolean isPalindrome(String s)
{ if (input == null)
return false;
else if(s.length() == 0 || s.length() == 1)
return true;
/* check for first and last char of String:
* if they are same then do the same thing for a substring
* with first and last char removed. and carry on this
* until you string completes or condition fails.
*/
if(s.charAt(0) == s.charAt(s.length()-1))
return isPalindrome(s.substring(1, s.length()-1));
return false;
}
Update
You are getting runtime error(NZEC) which means non-zero exit code. It means your program is ending unexpectedly. I don't see any reason except that your program doesn't have a null check. Otherwise, I have gone through your code carefully, you are doing the same thing which I have suggested.
I develop a function that reject number starting with 00 and 99.
public Boolean valideCode(EditText code_postal){
String number = code_postal.getText().toString();
if (number.charAt(0)==00){
}
return false;
}
How can i implement this function properly.
that if statement will always returns false.
One solution:
if (number.trim().startsWith("00") || number.trim().startsWith("99")){
System.out.println("not valid");
}
Use .startsWith():
if (number.startsWith("00") || number.startsWith("99")) ...
.charAt() returns a single character, not a string.
(out of sheer curiosity, why this? code_postal.getText().toString(); From the name of .getText(), you'd have figured out that it already returned a String... Bah.)
EDIT So, on demand, another version which checks by converting to an int first...
final int begin = Integer.parseInt(number.subString(0, 2));
if (begin % 99 == 0) // can only be true if number is 0 or 99
// etc
If I understand your question specially heading "lies between 00 && 99" you want this
try
{
String s = "45Abc";
Integer i = Integer.parseInt(s.substring(0,2));
if (i>00 && i<99)
System.out.println("True");
}catch (NumberFormatException e)
{
// TODO Auto-generated catch block
System.out.println("First two characters are not numbers");
}
Use your logic look like below
private boolean isValid(String str) {
if (str == null)
return false;
String tempStr = null;
try {
if (str.length() > 2) {
tempStr = str.substring(0, 2);
} else {
tempStr = str;
}
int number = Integer.parseInt(tempStr);
if (number >= 0 && number <= 99) {
return false; //in between 0 to 99
} else {
return true;
}
} catch (NumberFormatException e) {
}
return false;
}
You can use String class indexOf() method :
if (number.indexOf("00")==0 || number.indexOf("99")==0)
EDITED: - You need this as I understood from your question subject line "Check first two digit number lies between 00 && 99".
public static boolean isValid(String name) {
boolean isValid = true;
if(name.length()>2){
name = name.substring(0, 2);
}
try {
int number = Integer.parseInt(name);
if(number>-1 || number<100){
isValid = false;
}
}
catch(Exception e){
isValid = false;
}
return isValid;
}
To check if the Entered number starts with "00" or "99"
public Boolean valideCode(EditText code_postal){
String number = code_postal.getText().toString();
if(number.startsWith("00") || number.startsWith("99")){
return true;
}
return false;
}
To check if the Entered number is between "00" and "99"
public Boolean valideCode(EditText code_postal){
String number = code_postal.getText().toString();
String firstTwoDigits = number.substring(0,2);
if (Integer.valueOf(firstTwoDigits )>=0 && Integer.valueOf(firstTwoDigits )<=99){
return true;
}
return false;
}
Note: The title of your question and description are different. hence two answers.
Just to be different (and inefficient and impenetrable):
return !number.matches("^\s?(00|99).+");
I am trying to combine two boolean statements in order to validate a number.
This is the code for the two functions:
public boolean numberOne(String number)
{
int a = Integer.parseInt(number);
if(a >= 0 && a <= 7 && number.length() <= 1) {
return true;
}
else {
return false;
}
}
public boolean numberTwo(String number)
{
int b = Integer.parseInt(number);
if(b >= 01 && b <= 15 && number.length() <= 2) {
return true;
}
else {
return false;
}
}
Now I want to create another Boolean function to validate this number when both combined e.g. 215 would be true and 645 would be false.
How can I do this?
Thanks
Two changes. The first is a side note. This code
if (long_test) {
return true;
} else {
return false;
}
should be rewritten as this:
return long_test;
The other change described by dampee once he gets his variable names to match.
Ok. So you want to split the string and have the first number of the string compared to the first function and the last two numbers compared to the second function?
public boolean numberThree (String number) {
String part1 = number.substring(0, 1);
String part2 = number.substring(1);
return numberOne(part1) && numberTwo(part2);
}
I am trying to make a cee-lo program in simple, simple java. I'm just learning. However when I get to my instant w. (i have simplified it for the test) it just always returns false. I can't seem to figure out why. It even displays the correct data but when it compares it it fails.
public class ceeLo
{
public static void main (String [] args)
{
Scanner scan= new Scanner (System.in);
int [] die = new int [3];
int answer;
boolean roll = true;
boolean qualifed;
boolean instantW;
boolean instantL;
do
{
System.out.println("Roll the dice?");
answer = scan.nextInt ();
if (answer == 0)
roll= false;
else
{
int i;
for (i = 0; i < die.length; i++)
{
die[i]= rollin();
System.out.println(diceTxt(die[i]));
}
qualifed = (qualify (die));
System.out.println("Qualified = " + qualifed);
instantW = (easyW (die));
System.out.println("Instant win = " + instantW);
}
}
while (roll);
}
// Generate random numbers for the roll
public static int rollin ()
{
Random rand = new Random();
int die= rand.nextInt(6);
return die;
}
//Check if dice qualify with pair
public static boolean qualify (int [] die)
{
boolean qualify;
//Pair Qualifying roll
if (die[0] == die[1] || die[0] == die[2] || die[1] == die[2])
qualify = true;
else
qualify = false;
return qualify;
}
//Check if instant win
public static boolean easyW (int [] die)
{
boolean instantW;
// show contents of die [x] for testing
System.out.println (die[0] + "" + die[1] + "" + die[2]);
if (die[0] > 2 && die [1] > 2 && die[2] > 2)
instantW = true;
else;
instantW = false;
return instantW;
}
}
Remove semi-colon after else; it should be just else
I guess the reason is,
instantW = false; is being treated as separate statement not part of else block. Which is why instantW is always being assigned to false and returning false.
It is always better to use {} to define block even though they are single liners. It is my preference.
As Greg Hewgill suggested, using single statement instantW = die[0] > 2 && die [1] > 2 && die[2] > 2; would do good than if/else.
A better way to write boolean methods is really to do something like
boolean easyW(int[] die)
{
return (die[0] > 2 && die[1] > 2 && die[2] > 2);
}
Or even better (more general)
boolean easyW(int[] die)
{
for(int roll : die)
{
if(roll < 2)
{
return false;
}
}
return true;
}
But in your case, you have a ; after your else. Fixed version:
public static boolean easyW (int [] die)
{
boolean instantW;
// show contents of die [x] for testing
System.out.println (die[0] + "" + die[1] + "" + die[2]);
if (die[0] > 2 && die [1] > 2 && die[2] > 2)
instantW = true;
else
instantW = false;
return instantW;
}