Home > Back-end >  How do I one at a time, accept inputs from System.in.read()? What am I doing wrong?
How do I one at a time, accept inputs from System.in.read()? What am I doing wrong?

Time:09-17

This program is meant to accept input 1 at a time, from the user, to formulate a FizzBuzz(Count to 100. While counting, if the number is divisible by 3, say Fizz instead. If it is divisible by 5, say Buzz instead. If it is divisible by both, say FizzBuzz.) game after complete. The first input is intended to be the first digit of the length, and second input the second digit, and third input the third digit. The next two inputs will be Fizz and the second Buzz. However, after inputting the first character in the program, it will print twice? I don't understand what is happening with my script. Here is my program (using eclipse, if you need to know)

public class Game {
public static void runFizzBuzz(int length1, int length2, int length3, int fizz, int buzz) { 
    String out = ""; //what to print
    int foo = length1 * 100   length2 * 10   length3; //turns 3 digits into 3 digit num for program to read     
    for(int i = 0; i <= foo; i  ) {         
        out = ""; //resets out          
        if(i % fizz == 0) {             
            out  = "Fizz";              
        }           
        if(i % buzz == 0) {             
            out  = "Buzz";              
        }
        if(out == "") { //if neither of the above conditions pass, it will just do the number i
            out  = String.valueOf(i);   
        }
        System.out.println(out); //prints solution
    }
}
public static void main(String[] args) 
throws java.io.IOException {
    //parameters that System.in.read() should change
    int param1a; //digit 1 of length
    int param1b; //digit 2 of length
    int param1c; //digit 3 of length
    int param2; //fizz
    int param3; //buzz
    System.out.println("Param 1 digit 1 (length)");
    param1a = (char) System.in.read();
    System.out.println("Param 1 digit 2 (length)");
    param1b = (char) System.in.read();
    System.out.println("Param 1 digit 3 (length)");
    param1c = (char) System.in.read();
    System.out.println("Param 2 (fizz)");
    param2 = (char) System.in.read();
    System.out.println("Param 3 (buzz)");
    param3 = (char) System.in.read();
    System.out.println("Press e to exe"); //when i press e, print fizzbuzz game
    if((char) System.in.read() == 'e') {
        runFizzBuzz(param1a,param1b,param1c,param2,param3);
    }
}
}

Three side notes: I want this program to do all math in the runFizzBuzz() function, just so I can see it all together. Second, I'm kind of an idiot so please tell me how to add the solution to my script. Last, I've only just learned how to use System.in.read() so forgive me if the solution is obvious!

Thank you for any help I get!

CodePudding user response:

System.in.read is very unsuitable for what you are doing. It reads bytes, not characters, not the numbers that the characters represent either. The numbers are what you want, right?

Assuming your console is using UTF-8, and you entered "1" then pressed enter, you would have already entered more than 1 byte! You've entered one byte for the character "1", and also one byte for the new line character! (Note that the number of bytes that represent the new line character is OS-dependent, but judging from the behaviour you observed, it is most likely 1.)

So this line reads the byte for the character "1", which has the numerical value of 49:

param1a = (char) System.in.read();

Then the second prompt gets printed, and this line is reached:

param1b = (char) System.in.read();

That line will not stop the program and wait for you input, because remember that you entered two bytes? So there is one byte left unread in the input stream. That line will read that byte.

Then the third prompt gets printed, which is why you see an output like this:

Param 1 digit 1 (length)
1
Param 1 digit 2 (length)
Param 1 digit 3 (length)

Not only is the output not what you expect, param1a and param1b also has very wrong values.


You are shooting yourself in the foot by working at the "byte" level. I suggest using a Scanner, which can read the integers just by calling nextInt.

public static void main(String[] args) {
  int length;
  int fizz;
  int buzz;
  Scanner scanner = new Scanner(System.in);
  System.out.println("Param 1 (length)");
  length = scanner.nextInt();
  System.out.println("Param 2 (fizz)");
  fizz = scanner.nextInt();
  System.out.println("Param 3 (buzz)");
  buzz = scanner.nextInt();
  System.out.println("Press e to exe");
  if(scanner.next().equals("e")) {
    runFizzBuzz(length, fizz, buzz);
  }
}
public static void runFizzBuzz(int length, int fizz, int buzz) {
  for(int i = 0; i <= length; i  ) {
    if(i % fizz == 0 && i % buzz == 0) {
      System.out.println("FizzBuzz");
    } else if (i % fizz == 0) {
      System.out.println("Fizz");
    } else if (i % buzz == 0) {
      System.out.println("Buzz");
    } else {
      System.out.println(i);
    }
  }
}

CodePudding user response:

You should use Scanner for this, but if you don't want to use it, you could use InputStreamReader and BufferedReader, though I don't recommend it.

public static void main(String[] args)throws IOException {
  int length;
  int fizz;
  int buzz;
  InputStreamReader read = new InputStreamReader(System.in);
  BufferedReader in = new BufferReader(read);
  System.out.println("Param 1 (length)");
  length = Integer.parseInt(in.readLine());
  System.out.println("Param 2 (fizz)");
  fizz = Integer.parseInt(in.readLine());
  System.out.println("Param 3 (buzz)");
  buzz = Integer.parseInt(in.readLine());
  System.out.println("Press e to exe");
  if(in.readLine().equals("e")) {
    runFizzBuzz(length, fizz, buzz);
  }
}
  • Related