1

I need to use the method

    public static String readString() { 

    return input.nextLine(); 
}

In order to use the Scanner method next.Line(), its just a requirement of the project, the thing is that when I use the static method ProjectUtils.readString() to gather the user input as a string it just throws me a lot of errors, I cant understand why, Im using it this way

       public static void encryptAString() {

        ProjectUtils.println("Enter the phrase and the key");
        String p = ProjectUtils.readString();
        ProjectUtils.println("Enter key");
        int k = ProjectUtils.readInteger();
        ProjectUtils.println(EncryptString.encryptString(p,k ));

But always ends up terminating and throwing this

Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at ProjectUtils.readInteger(ProjectUtils.java:24)
at ProjectUtils.encryptAString(ProjectUtils.java:88)
at StringMenuManager.run(StringMenuManager.java:37)
at ProjectUtils.operationsOnStrings(ProjectUtils.java:69)
at MainMenuManager.run(MainMenuManager.java:47)
at P1Main.main(P1Main.java:9)

Thanks in advance.

MCVE

The main class

public class Main {

    public static void main(String[] args) {
        MCVE.encryptAString();
    }
}

The MCVE method or ProjectUtils class in the original project

import java.util.Scanner;





public class MCVE {

private static final Scanner input = new Scanner(System.in);

public static void println(String s) { 
    System.out.println(s); 
}
public static int readInteger() { 
    // for the moment, just assume that the input is a
    // valid integer.... but eventually we want to be 
    // more robust and explicitly read and test first if
    // the input was really an integer or not....
    return input.nextInt(); 
}
public static String readString() { 
    // for the moment, just assume that the input is a
    // valid String.... but eventually we want to be 
    // more robust and explicitly read and test first if
    // the input was really an integer or not....
    return input.nextLine(); 
}

public static void encryptAString() {

    MCVE.println("Enter the phrase and the key");
    String p = MCVE.readString();
    int k = MCVE.readInteger();
    MCVE.println(EncryptString.encryptString(p,k ));

     }
   }

And the encryption class

 public class EncryptString {
 private static final int ALENGTH = 26; 

/**
 * Encrypt a string using a given key value. 
 * @param s the String to be encrypted
 * @param key the key 
 * @return the encrypted string
 */
public static String encryptString(String s, int key) {
    // if the key value is not in the accepted range (-25..25)
    // the encrypted string is the same as the input string
    if (key < -25 || key > 25) 
        return s; 

    // the key is valid, construct the encrypted string as 
    // described in P1 specs...
    String newString = "";
    for(int x = 0; x<s.length(); x++)
    {
        if(((int)s.charAt(x)>64&&(int)s.charAt(x)<123))
            newString = newString + encryptChar(s.charAt(x), key);
        else
            newString = newString + s.charAt(x);

    }
    return newString;
}


/**
 * Encrypt a particular character.
 * @param ch the character to encrypt - assumed to be a letter ‘a’..’z’ or ‘A’..’Z’
 * @param key the key to be used. It is assumed to be a value in range (-25..25)
 * @return the new character after encryption
 */
private static char encryptChar(char ch, int key) {
    // PRE: ch is a letter 'A'..'Z' or 'a'..'z'
    // PRE: key is an integer in the range -25..25

    int base; 
    if (Character.isUpperCase(ch))
        base = (int) 'A'; 
    else 
        base = (int) 'a'; 
    return (char) (Math.abs((((int) ch - base) + key + ALENGTH) 
                                % ALENGTH) + base); 
}

}

laylarenee
  • 3,148
  • 7
  • 30
  • 40
Daniel Rodríguez
  • 494
  • 3
  • 6
  • 13
  • What is your input? What does `readInteger` do with it? – Sotirios Delimanolis Sep 26 '15 at 01:25
  • Just added it forgot to add the Enter key line asking the user for the encryption key, they then are sent to a method in class EncryptString that receives a string and an int – Daniel Rodríguez Sep 26 '15 at 01:26
  • Thanks for the reply, the thing is it doesn't even let me input the int, just after I enter the string it terminates and throws that – Daniel Rodríguez Sep 26 '15 at 01:34
  • 1
    Please post a complete and reproducible example, an MCVE. – Sotirios Delimanolis Sep 26 '15 at 01:34
  • [Here's](http://stackoverflow.com/help/mcve) the definition of an MCVE. – Sotirios Delimanolis Sep 26 '15 at 01:44
  • Thanks for the definition, I just moved the core code for that method to another project and it worked perfectly, using the exact same functions, gonna post it instead of that wrong MCVE I wrote – Daniel Rodríguez Sep 26 '15 at 01:52
  • For me too, I don't understand why in the original big project it wont work... – Daniel Rodríguez Sep 26 '15 at 02:00
  • Also in the project when the method executes, both lines Enter phrase and Enter key appear at the same time, not like in the MCVE although the both are written the same just in different classes, could that hint to the problem? – Daniel Rodríguez Sep 26 '15 at 02:12
  • What does `readString()` actually read in the original project? Also if it asks you for an int immediately afterwards, can you input that int without error? – Cinnam Sep 26 '15 at 02:18
  • readString() returns input.nextLine(); just like in the MCVE, and actually yes I can, it shows me both lines of Enter phrase and Enter key but the error only appears if I enter a non-number character – Daniel Rodríguez Sep 26 '15 at 02:21
  • I reversed the order of operation and it lets me input a number for the key, but after just hitting enter for the input it shows the Enter phrase line and terminates – Daniel Rodríguez Sep 26 '15 at 02:25
  • What I meant was what is the actual String that `input.nextLine()` returns in the original project. This seems to be some newline issue. `nextLine()` probably reads an empty line (which you didn't enter) and then `nextInt()` of course only accepts int. Try replacing `nextInt()` with `next()` and just try printing what you get – Cinnam Sep 26 '15 at 02:29
  • So I just tried what you suggested and yes I can do it with only next(), but how can I input a whole sentence using only the next() function or how do I fix this missing line problem? Thanks for pointing the exact problem btw man – Daniel Rodríguez Sep 26 '15 at 02:33
  • Have you replaced `nextLine()` with `next()`? If so, that's not what I was suggesting - try keeping `nextLine()`, replacing `nextInt()` with `next()` and printing both values you get – Cinnam Sep 26 '15 at 02:38
  • Ok but I cant replace nextInt for next because there are many parts of the menus of the project that depend on that so it wont run, I tried adding another inputnextLine() below the one assigned to the string and it "worked" but when I send the values to the encrypting class it doesnt returns anything, I'm still trying to do what you are suggesting but noting will run, any other suggestions? – Daniel Rodríguez Sep 26 '15 at 02:44
  • 1
    This might work, but it's not really a solution, just a temporary workaround - take your String from the second `input.nextLine()`. The first one will just consume the odd newline, if that's what's causing this. – Cinnam Sep 26 '15 at 02:46
  • I just did that, and IT WORKED! Thanks man really for your help and everything :D , how can I commend you for this? Post that comment as a solution so I can give you positive stuff – Daniel Rodríguez Sep 26 '15 at 02:49
  • You're welcome, but remember we didn't really fix the underlying problem - there's a newline that shouldn't be there. Maybe it will work well, but maybe you will run into this problem again if you have more inputs in the project – Cinnam Sep 26 '15 at 02:50
  • And what could be creating this new line? It worked well in the MCVE so I guess it could be another classes from where this is being called? – Daniel Rodríguez Sep 26 '15 at 02:51
  • I guess one way to find out would be to carefully add things from the big project to the MCVE (or removing things from the big project) to see when it stops/starts working correctly – Cinnam Sep 26 '15 at 02:53

1 Answers1

1

Although I'm not sure about the exact underlying problem, there seems to be a newline in your input that shouldn't be there. It's causing the first input.nextLine() to read (presumably) an empty line.

A temporary workaround would be to consume this newline by calling readString() and ignoring the return value, then reading the actual String input with another readString() call.

Cinnam
  • 1,872
  • 1
  • 13
  • 23
  • Thanks for all the help, I just found this: http://stackoverflow.com/questions/13102045/skipping-nextline-after-using-next-nextint-or-other-nextfoo-methods Other people had this problem too. Thanks again, goodnight – Daniel Rodríguez Sep 26 '15 at 03:04