0

I have a user enter their social security number (fake number) and I need it in the format of 111-11-1111 including the dashes. If the user enters the information without the dashes, or goes over 999-99-9999, the program prompts the user to enter the correct information. Here is my code, how do I fix this? Also, can I use a StringBuilder for any part of this?

import java.util.Scanner;
import java.lang.StringBuilder;
import java.lang.Math; 
 class TaxReturn
 {
 public static void main(String[] args)
 {
 String firstName, mI, lastName;
 char M;
 char S;
 int SSN;
 final int SSNLimit = 999999999;
 int zip;
 int income;
 int pets;
 int vehicle;
 int toaster;


 //Start string firstName   
  Scanner inputDevice = new Scanner(System.in);
  System.out.print("First name: ");
  firstName = inputDevice.next();

 //Start middle name
  System.out.print("Middle initial: ");
  mI = inputDevice.next();

 //Start lastName
  System.out.print("Last name: ");
  lastName = inputDevice.next();

 //Start SSN (Social Security Number)
  System.out.print("What is your Social Security Number?: ");
  SSN = inputDevice.nextInt();
  while(SSN > SSNLimit)
  {
     System.out.print("Invalid entry, please enter a valid Social Security Number");
     System.out.print("\nPlease enter your Social again:");
     SSN = inputDevice.nextInt();
  }
}
}
leppie
  • 115,091
  • 17
  • 196
  • 297
Nick Wilson
  • 61
  • 1
  • 10
  • It would really help if you tell us the error you are getting so we can help you faster. – lightning_missile Jan 04 '15 at 06:07
  • I'm not getting an error. in the last part of the code, i would like to know if there is a way I can make the code recognize dashes in a social security number. Other then all numbers. example 999-99-9999 and not 999999999 – Nick Wilson Jan 04 '15 at 06:11
  • 1
    make use of regular expression "^\d{3}-\d{2}-\d{4}$" to detect whether it is in correct format or not – Ajinkya Pisal Jan 04 '15 at 06:13
  • @Ajinkay Pisal, i'm not familiar with that. Is there somewhere I can read about it? What is it the technical name for that? Regular expression? – Nick Wilson Jan 04 '15 at 06:19
  • @Nick Wilson http://docs.oracle.com/javase/tutorial/essential/regex/ – lightning_missile Jan 04 '15 at 06:20

4 Answers4

0

Since you are accepting ssn as integer, you could check for range of number i.e. 9digit number range and can do something like:

final int ssnEndLimit = 999999999;
final int ssnStartLimit = 100000000;
while(SSN > ssnEndLimit || SSN < ssnStartLimit) {//if its not 9 digits exactly
    ...
}
//Now Format as per OP's requirement
String formattedSSN = formatSSN(SSN);

private static String formatSSN(int ssn) {
    DecimalFormat ssnDecimalFmt = new DecimalFormat("000000000");
    String ssnRawString = ssnDecimalFmt.format(ssn);
    MessageFormat ssnMsgFmt = new MessageFormat("{0}-{1}-{2}");
    String[] ssnNumArr = {ssnRawString.substring(0, 3), ssnRawString.substring(3, 5), ssnRawString.substring(5)};
    return ssnMsgFmt.format(ssnNumArr));
}
SMA
  • 36,381
  • 8
  • 49
  • 73
0

You are using nextInt() to read a value. But in your case it is not a integer value as it contains the "-". Hence use input as a string then apply regular expression to check whether entered string is valid format.

For matching of SSN you can use regular expression

String pattern = "^\d{3}-\d{2}-\d{4}$";

  // Create a Pattern object
  Pattern ssnPattern = Pattern.compile(pattern);
  SSN = inputDevice.next();
  // Now create matcher object.
  Matcher m = ssnPattern.matcher(SSN);
  if(m.matches()){
    //valid
  }else{
   // invalid
  }

Or as given in below comment (in one line of code)

 if (SSN.matches("^\\d{3}-\\d{2}-\\d{4}$")){
  //valid ssn
  }
  else {
  //invalid ssn 
  }

But you should stick to first approach as it SSN validation will get executed many times. As matcher gets precompiled hence it is efficient that string.matches which gets recompiled every time code is excuted

What's the difference between String.matches and Matcher.matches?

Community
  • 1
  • 1
Ajinkya Pisal
  • 551
  • 1
  • 6
  • 24
  • 1
    You could use `if (!SSN.matches(pattern)) {//...error...}` and escape "\" in your regex. – SMA Jan 04 '15 at 06:24
  • Thanks, i'm going to read up on the link you provided and use a string instead. – Nick Wilson Jan 04 '15 at 06:26
  • @almasshaikh your code does work. But for you knowledge Matcher is better than string.matches when some piece is excuted many times. – Ajinkya Pisal Jan 04 '15 at 06:33
  • Dont reinvent wheel when you already have API which does the same. You should avoid over optimising the code.. – SMA Jan 04 '15 at 06:40
  • @almasshaikh Just making it work and making it work efficiently are two different thing. Making it work in efficient way makes you better programmer. Period. – Ajinkya Pisal Jan 04 '15 at 06:43
  • So in that case why are you recommending pattern matching when integer comparison is way better? – SMA Jan 04 '15 at 06:53
  • @almasshaikh please read the question. OP wants SSN in dash format. – Ajinkya Pisal Jan 04 '15 at 06:55
0

Here is the modified version base on you code.

import java.util.Scanner;

public class TaxReturn {

public static void main(String[] args) {
    String firstName, mI, lastName;
    char M;
    char S;
    int SSN;
    final int SSNLimit = 999999999;
    int zip;
    int income;
    int pets;
    int vehicle;
    int toaster;

    // Start string firstName
    Scanner inputDevice = new Scanner(System.in);
    System.out.print("First name: ");
    firstName = inputDevice.next();

    // Start middle name
    System.out.print("Middle initial: ");
    mI = inputDevice.next();

    // Start lastName
    System.out.print("Last name: ");
    lastName = inputDevice.next();

    // Start SSN (Social Security Number)
    System.out.print("What is your Social Security Number?: ");
    while (true) {
        String s = inputDevice.next();
        if (s.matches("^\\d{3}-\\d{2}-\\d{4}$")) {
            int i = Integer.valueOf(s.replaceAll("-", ""));
            if (i < SSNLimit) {
                SSN = i;
                System.out.println("SSN is " + SSN);
                break;
            } else {
                System.out.print("Invalid entry, please enter a valid Social Security Number");
                System.out.print("\nPlease enter your Social again: ");
                continue;
            }
        } else {
            System.out.print("Invalid entry, please enter a valid Social Security Number");
            System.out.print("\nPlease enter your Social again: ");
            continue;
        }
    }
    inputDevice.close();
}
}
alijandro
  • 11,627
  • 2
  • 58
  • 74
  • I get this error when I prompt the correct social. Exception in thread "main" java.lang.IllegalStateException: Scanner closed – Nick Wilson Jan 04 '15 at 16:54
0

Using regex might be better, but you can also make a solution without it. You might want to validate the social security number like this:

//I put the validation inside a method to make your code easier to understand
//input should have "-", so I'm passing it as a string
public static boolean validate(String s) {
    StringBuilder number = new StringBuilder(s);
    if (number.charAt(3) == '-' && number.charAt(6) == '-') { //check for "-"
        //if the -s is in correct indexes, remove the -s to test all other characters
        number.deleteCharAt(3);
        number.deleteCharAt(5);
        for (int i = 0; i < number.length(); i++) { //are all other characters digits?
            if (!Character.isDigit(number.charAt(i))) {
                return false;
            }
        }
        //now compute if it is over 999999999
        return (Integer.parseInt(number.toString()) <= 999999999);
    } else {
        return false;
    }
    } 

You can use it like this:

while(!validate(SSN)) //SSN is String in this case
{
    System.out.print("Invalid entry, please enter a valid Social Security Number");
    System.out.print("\nPlease enter your Social again:");
    SSN = inputDevice.next();
    }
lightning_missile
  • 2,821
  • 5
  • 30
  • 58