2
\$\begingroup\$

Reads the user's first and last name (an entire line as a single string), then prints the last name followed by a comma and the first initial. Ensure the code re-prompts until the user types a name that is at least 5 letters total in length and has at least one space in it. For example:

Type your name: Jessica Miller
Your name is: Miller, J.

A few questions I have about my code:

  1. Is there a difference between breaking out of a loop with a break statement, and meeting the condition for correctName?
  2. Did I make my program do unnecessary things? I'd like to answer this for myself, but I may've made it unnecessarily complex, or even buggy, due to my thought process. For instance, can I check if there's a space in my first conditional, where I check if the length of the line is greater than or equal to five?

Any feedback is welcome!

Scanner console = new Scanner(System.in);
boolean correctName = false;

while(correctName != true) {
    System.out.print("Type your name: ");
    String line = console.nextLine();
    if(line.length() >= 5) {
        StringTokenizer lineTokens = new StringTokenizer(line);
        while(lineTokens.hasMoreTokens()) {
            if(lineTokens.countTokens() >= 2) {
                String first = lineTokens.nextToken();
                String last = lineTokens.nextToken();
                String name = (last + ", " + first.substring(0, 1) + ".");
                System.out.println("Your name is: " + name);
                correctName = true;
            } else {
                String checkSpace = lineTokens.nextToken();
                for(int i = 0; i < checkSpace.length(); i++) {
                    if(checkSpace.charAt(i) == ' ') {
                        break;
                    } else {
                        System.out.println("Error, must be at least 5 chars with a space.");
                        break;
                    }
                }
           }
        }
    } else {
        System.out.println("Error, must be at least 5 chars with a space.");
    }
}
\$\endgroup\$
3
\$\begingroup\$

Methods

I'm assuming this chunk of code sits in your main() method, and I think one quick way of improving it is to break it into two methods - one that returns a validated user input (at least 5 chars with a space), and one for the actual work.

When you separate them, you will also realize that you only need to print your validation message once, instead of twice as you are doing currently (to check for length, and to check for a space).

Stricter input validation

Type your name: Jessica Miller

Your name is: Miller, J.

Since you actually require the initial of the first name, you also need to check that the space is not at the start or the end of the input, as otherwise you only have one name. Consider this:

private static void test(String input) {
    // A Scanner works in a similar way to the legacy StringTokenizer class
    try (Scanner scanner = new Scanner(input)) {
        while (scanner.hasNext()) {
            System.out.printf("Token: [%s]%n", scanner.next());
        }
    }
}

test("hello world");
// Token: [hello]
// Token: [world]

test(" helloworld");
// Token: [helloworld]

test("helloworld ");
// Token: [helloworld]

An example implementation to validate for this can be:

private static final int REQUIRED_LENGTH = 5;

private static String getInput(Scanner scanner) {
    String result = scanner.nextLine();
    while (result.length() < REQUIRED_LENGTH ||
            !result.contains(" ") ||
            result.startsWith(" ") ||
            result.endsWith(" ")) {
        System.out.println("Try again.");
        result = scanner.nextLine();
    }
    return result;
}

Still, this can be defeated if there are multiple spaces and they happen to also be at the start and/or the end. Perhaps a regex solution may be better here... this shall be left as an exercise for the reader.

Boolean flags

Going back to your main() method, you wouldn't require correctName if you have separated the logic that validates the user input and the actual work.

\$\endgroup\$
2
\$\begingroup\$

In answer to the first part of your question, there shouldn't be any difference between break and meeting the conditional. If there were more code after the if...else statement then the break would exit the loop before that code while the conditional would not. Just something to keep in mind if you expand the program. However, if you do as h.j.k suggested, it should't be necessary at all and that would be much better practice.

Also, this isn't really that important but I would suggest making the prompt to enter name clearer. If I were to run that program without seeing the code I would probably just enter my first name which is not what you're looking for.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.