How to make sure the user only inputs 1s and 0s? - java

I have this loop that keeps the user stuck inputting values until he/she, inputs something valid, in this case it has to be binary numbers that must be the size of a certain type of variable. Nonetheless, I don't know how to make the loop continue in the case that the user inputs a number made up of something different aside from 1s and 0s.
I was thinking of using string.contains(), but that cannot account for every number. Here's my loop:
while((double)inputStr.length() != table.getNumberOfVariables() ||
inputStr.replaceAll("\\D","").length() != inputStr.length() ||
Double.parseDouble(inputStr) > 1){
This line: Double.parseDouble(inputStr) > 1 was supposed to accomplish that, but I'm dealing with decimal numbers, so if the input is 10 or 100, they're rendered invalid.

In your case, rather than using \D in your regex (anything that's not a digit), you must be more specific: [^01] (meaning: anything not a zero or one).
while((double)inputStr.length() != table.getNumberOfVariables() ||
inputStr.replaceAll("[^01]","").length() != inputStr.length() ||
Double.parseDouble(inputStr) > 1){
It doesn't win you a prize for nice code though, because it is hard for the reader of this code to find out what you are doing. It's better to turn what you're doing into a method with a clear name, like:
public static boolean containsOnly(String s, String only) {
for (int i = 0; i < s.length(); i++) {
if (only.indexOf(s.charAt(i)) == -1)
return false;
}
return true;
}
As it happens, the Apache commons-lang3 library has such a method in it: StringUtils.containsOnly. They have many methods for String manipulation that are clearer and often much faster than using regexes.

You can use a regular expression to validate the binary string:
String s = "0101110";
if (s.matches("[01]++")) {
System.out.println("ok");
} else {
System.out.println("invalid");
}

Related

Recursive java method to parse a string with condition?

Fairly new to java and programming.
Wrote this recursive method, with the objective of asking for a valid string that is both an integer and greater than 0:
private int getDimension(String tableElement){
Integer Input= 0;
System.out.println("Define table rows "+tableElement+"'s."
+"Enter an integer >= 1:");
if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)
return getDimension(tableElement);
return Input;
}
I'd like to stick to using a short and recursive method. It seems to handle the >= 0 logic fine, but blows up when i pass it something other than an integer.
Can someone explain why does that happen to me please?
hasNextInt() doesn't actually consume your input, so you're stuck with the same non-int input on your next call.
Simply spoken, your code doesn't make much (any?) sense.
First of all, there is not really a point in using a recursive method that asks the user for input; and that does not at all do anything about the argument passed to it!
private int getDimension(String tableElement){
Integer Input= 0;
Bad: you keep up mixing int and `Integer. They are not the same. And - read about java coding style guides. Variable names start lower case!
if( !Reader.hasNextInt() || (Input=Input.parseInt(Reader.nextLine())) <= 0)
The first condition gives:
true: when there is NO int ...
false: when there is an int
true leads to: calling your method again without retrieving a value from the reader.
false leads to parsing an int; and checking its value for <= 0.
In one case, you are doing a recursive call; completely ignoring the input you got from the reader; in the other case, you returning 0; or that value in input.
Solution: do something like:
while (true) {
if (reader.hasNextInt()) {
input = reader.nextInt();
break;
}
// there is no number!
read.nextLine(); // consume & throw away non-number!
print "Enter a number"
}
instead.
But seriously: start with throwing away this code.
Final side note: you do Input.parseInt() ... but that is a static method on the Integer class. Just call that as Integer.parseInt() instead! But as said; throw away your code; and learn how to properly use that Scanner class; start reading here.
Because the user can enter anything, you must always read in the line, then compare it:
String num = Reader.nextLine();
return num.matches("[1-9][0-9]*") ? Integer.parseInt(num) : getDimension(tableElement);
Here I've use regex to figure out if it's a positive number; the expression means "a 1-9 char followed by 0 or more of 0-9 chars"

How to validate phone number

I am trying to validate phone numbers in java. In my country, phone numbers either begin with 9 or 8 and only have 8 numbers. I have done
try {
Integer.parseInt(phoneNo);
}
catch (NumberFormatException e) {
msg += "Plese enter amount in Integers.\n";
}
if (phoneNo.length() == 0)
msg += "Please Enter Phone Number.\n";
if (phoneNo.length() != 8)
msg += "Invalid Phone Number.\n";
However I need to validate when the first digit of the number isn't 9 or 8. I am not entirely sure of how I am supposed to do that. Please explain how your code works as I am a student and I am trying to learn.
Just in case you are looking for a regular expression solution.
You can do use the following pattern ^(?=(?:[8-9]){1})(?=[0-9]{8}).* to perform the check.
Essentially what it does is;
From first character position ^
Look ahead and see if the first character is a 8 or 9 (?=(?:[8-9]){1})
Then see if there are a total of 8 digits (?=[0-9]{8})
If the above conditions is a match then mark this as matched .*
public static void main(String[] args) {
String telephoneNr = "88765432";
if (telephoneNr.matches("^(?=(?:[8-9]){1})(?=[0-9]{8}).*")) {
System.out.println("Valid phone number!");
}
else {
System.out.println("Invalid!");
}
}
Output:
Valid phone number!
The methods that you need to put this together are readily available on the String and Character classes.
Here is an example program that does what you are looking for:
public class Foo {
public static void main(String[] args) {
// First try null and the empty string
System.out.println(isValidPhoneNumber(null));
System.out.println(isValidPhoneNumber(""));
// Now try an otherwise valid string that doesn't have the right first character
System.out.println(isValidPhoneNumber("01234567"));
// Now try an invalid string
System.out.println(isValidPhoneNumber("9a934581"));
// Finally a valid number
System.out.println(isValidPhoneNumber("94934581"));
}
static boolean isValidPhoneNumber(String phoneNo) {
// First validate that the phone number is not null and has a length of 8
if (null == phoneNo || phoneNo.length() != 8) {
return false;
}
// Next check the first character of the string to make sure it's an 8 or 9
if (phoneNo.charAt(0) != '8' && phoneNo.charAt(0) != '9') {
return false;
}
// Now verify that each character of the string is a digit
for (char c : phoneNo.toCharArray()) {
if (!Character.isDigit(c)) {
// One of the characters is not a digit (e.g. 0-9)
return false;
}
}
// At this point you know it is valid
return true;
}
}
The output it produces is:
false
false
false
false
true
The final for-each loop could avoid re-checking the first character by using a for loop with an explicit counter, but the performance gain of not checking a single int doesn't outweigh the cleaner code and better readability of the for each construct.
Edit: also please note that I removed the validation error messages from the original question for better readability as the OP asked to explain what the code was doing.
Instead of taking the phone number in a Integer variable take it in a String variable.
Then check whether the 1st number is 9, 8 or not by using stringVariable.charAt(0)
and for length of the phone number use int len=stringVariable.length();
You can check the first character of the phoneNo:
if (phoneNo.charAt(0) != '9' && phoneNo.charAt(0) != '8') {
// the first character is not a 9 or an 8
}
Documentation for charAt from Oracle.

While not (or equivalent) java

I'm making a program with Java that needs to involve some error checking. I can stop users from entering bad numerical inputs like this (assume the input scanner has already been created):
while (n == 0){
System.out.println("Can't use 0 as a denominator! Please enter a real, nonzero number");
n = input.nextInt();
}
But how do I stop users from entering an invalid string? I can't use !=, because strings can only be compared with the string.equals() method, right? So, is there a while not loop? ie:
while !(string.equals("y") || string.equals("n")){
//here have code
}
Or something of that nature?
While there is no such thing as a while-not loop, you can always invert the condition:
while (!(string.equals("y") || string.equals("n"))){
This is read, "while the string is not equal to "y" or "n"".
You could also apply DeMorgan's identity to rewrite this as:
while (!(string.equals("y")) && !(string.equals("n"))){
which is a bit clearer as "While the string isn't equal to "y" and isn't equal to "n"".
There isn't a while-not instruction, but you can simply negate the condition in a normal while loop. Try this:
while (!string.equals("y") && !string.equals("n"))
Or even better, to guard against the case where the string is null and/or it's in a different case:
while (!"y".equalsIgnoreCase(string) && !"n".equalsIgnoreCase(string))
You almost get it, just change where you position your !
like this:
while (!(string.equals("y") || string.equals("n")))
Why not try regex?
Scanner sc = new Scanner(System.in);
String string = sc.nextLine();
while (!string.matches("(?i)^(?:y|n|yes|no)$"))
{
System.out.println("Invalid input...");
string = sc.nextLine();
}
boolean answer = string.matches("(?i)^(?:y|yes)$");

I'm confused about Logical Operators, can someone help me clear up my mess? Multiple arguments?

this is my first post here, but I often use this site to help me with coding issues I run into. I'm an intermediate level Java programmer. I'm going to college next year and I'm considering a minor in Computer Science.
I'm making a pretty basic mock-credit card validator that reads in a credit card, checks if it's valid, and then emails information to the user. This is not to be used for anything other than educational purposes.
So I have a bit of code that checks multiple conditions for a credit card string that someone types in. For example, as you'll see, it checks the starting digit, the name of the card, and the number of digits. It checks the conditions, and if they are met the program continues, if not it gives an error and stops immediately. I'm like 99% sure that I'm entering my information in correctly, but it gives me the error no matter what and I'm at a loss here.
Sorry if I typed so much, again I'm new here. So I'm asking for help on my logic here, thanks!
if((cardType.equals("Visa") && card.substring(0).equals("4")) && (length == 13 || length == 16)){
System.out.println("Thank you, next step");
cardValid = true;
}
if((cardType.equals("Master Card")) && (card.substring(0,1).equals("51") || card.substring(0,1).equals("52") || card.substring(0,1).equals("53") || card.substring(0,1).equals("54") || card.substring(0,1).equals("55")) && (length == 16)){
System.out.println("Thank you, next step");
cardValid = true;
}
if((cardType.equals("American Express") && card.substring(0,1).equals("37") && length == 15)){
System.out.println("Thank you, next step");
cardValid = true;
}
if(cardValid != true){
System.out.println("ERROR");
System.exit(0);
}
}
You are not using the substring method correctly. To get the first character as a substring, you need to use the two-argument version of substring, to supply a beginning index (inclusive) and an ending index (exclusive).
The substring begins at the specified beginIndex and extends to the character at index endIndex - 1.
Parameters:
beginIndex - the beginning index, inclusive.
endIndex - the ending index, exclusive.
(The one-argument version of substring takes a substring from the given index through the rest of the string.)
The substring begins with the character at the specified index and extends to the end of this string.
Replace
card.substring(0).equals("4")
with
card.substring(0, 1).equals("4")
or just compare the character there.
card.charAt(0) == '4'
Next, to get the first two characters, again take into account the fact that the ending index is exclusive. Replace
card.substring(0,1).equals("37")
with
card.substring(0,2).equals("37")
The following should work.
You had some syntactic errors with String.substring. You can refer to a full list of String functions in the java documentation below:
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
if((cardType.equals("Visa") && card.substring(0,1).equals("4")) && (length == 13 || length == 16)){
System.out.println("Thank you, next step");
cardValid = true;
}
if((cardType.equals("Master Card")) && (card.substring(0,2).equals("51") || card.substring(0,2).equals("52") || card.substring(0,2).equals("53") || card.substring(0,2).equals("54") || card.substring(0,2).equals("55")) && (length == 16)){
System.out.println("Thank you, next step");
cardValid = true;
}
if((cardType.equals("American Express") && card.substring(0,2).equals("37") && length == 15)){
System.out.println("Thank you, next step");
cardValid = true;
}
if(!cardValid){
System.out.println("ERROR");
System.exit(0);
}
}

String not populating properly

I am writing a program that is going to read a string from a file, and then remove anything that isn't 1-9 or A-Z or a-z. The A-Z values need to become lowercase. Everything seems to run fine, I have no errors, however my output is messed up. It seems to skip certain characters for no reason whatsoever. I've looked at it and tweaked it but nothing works. Can't figure out why it is randomly skipping certain characters because I believe my if statements are correct. Here is the code:
String dataIn;
int temp;
String newstring= "";
BufferedReader file = new BufferedReader(new FileReader("palDataIn.txt"));
while((dataIn=file.readLine())!=null)
{
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
i++;
}
System.out.println(newstring);
}
So to give you an example, the first string I read in is :
A sample line this is.
The output after my program runs through it is this:
asmlietis
So it is reading the A making it lowercase, skips the space like it is suppose to, reads the s in, but then for some reason skips the "a" and the "m" and goes to the "p".
You're incrementing i in the each of the blocks as well as in the main loop "header". Indeed, because you've got one i++; in an else statement for the last if statement, you're sometimes incrementing i twice during the loop.
Just get rid of all the i++; statements other than the one in the for statement declaration. For example:
newstring="";
for(int i=0;i<dataIn.length();i++)
{
temp=(int)dataIn.charAt(i);
if(temp>46&&temp<58)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>96&&temp<123)
{
newstring=newstring+dataIn.charAt(i);
}
if(temp>64&&temp<91)
{
newstring=newstring+Character.toLowerCase(dataIn.charAt(i));
}
}
I wouldn't stop editing there though. I'd also:
Use a char instead of an int as the local variable for the current character you're looking at
Use character literals for comparisons, to make it much clearer what's going on
Use a StringBuilder to build up the string
Declare the variable for the output string for the current line within the loop
Use if / else if to make it clear you're only expecting to go into one branch
Combine the two paths that both append the character as-is
Fix the condition for numbers (it's incorrect at the moment)
Use more whitespace for clarity
Specify a locale in toLower to avoid "the Turkey problem" with I
So:
String line;
while((line = file.readLine()) != null)
{
StringBuilder builder = new StringBuilder(line.length());
for (int i = 0; i < line.length(); i++) {
char current = line.charAt(i);
// Are you sure you want to trim 0?
if ((current >= '1' && current <= '9') ||
(current >= 'a' && current <= 'z')) {
builder.append(current);
} else if (current >= 'A' && current <= 'Z') {
builder.append(Character.toLowerCase(current, Locale.US));
}
}
System.out.println(builder);
}

Categories

Resources