0

I am just polishing my java skills and I wrote out this code to play around with keyboard input and do while loops.

package Chapter3;

import java.io.IOException;

public class convertCase {

public static void main(String args[]) throws IOException {
    char ch = 'a';

    do {
        System.out.println("please type in a value: ");
        ch = (char) System.in.read();

        if((int) ch < 96) {
            ch += 32;
            int newCh = (int) ch;
            System.out.println("The lowercase version is: " + (char)newCh);
        }

        else if((int) ch >96) {
            System.out.println("You have typed in" + ch);
            ch -= 32;
            int newCh = (int) ch;
            System.out.println("the uppercase version is: " + (char)newCh);
        }
    } while(ch!='.');
}

}

Problem is that when I test it the 'while loop' runs twice before asking for input instead of just the once:

please type in a value: 
a
You have typed ina
the uppercase version is: A
please type in a value: 
The lowercase version is: *
please type in a value: 
L
The lowercase version is: l
please type in a value: 
The lowercase version is: *
please type in a value: 

Can someone bring clarity to this situation??

Wouter J
  • 41,455
  • 15
  • 107
  • 112
Monmon
  • 5
  • 6

4 Answers4

3

That's because

System.in.read();

takes in every key pressed. that is, in your case, the 'a' key, and the 'return' key.

If you want your functionality then use the following:

Scanner scanner = new Scanner(System.in);

And then use:

String line =(char)scanner.nextLine();

and then parse the value.

Benjamin
  • 2,257
  • 1
  • 15
  • 24
Tamby Kojak
  • 2,129
  • 1
  • 14
  • 25
2

You are processing the newline character as if it is legitimate input. You should either read the entire line (including the newline, perhaps using a Scanner) and then process the first character of the line or simply add a test to skip newlines in your loop logic.

P.S. Converting case by adding or subtracting 32 is a really awful approach. It won't work with anything but a-z and A-Z (in the English alphabet). It won't work for most characters outside the Basic Latin block and shouldn't be used at all for characters that have no alternate case (such as newline). You should be using Character.toUpperCase() and Character.toLowerCase() instead.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
2

It is looping twice because it is processing the newline that follows each character.

Jiminion
  • 5,080
  • 1
  • 31
  • 54
1

Answer taken from Book "Java: A Beginner's Guide"

The answers mentioned above are right as well. Just for more clarification, I will post this.

do {
        System.out.print("Pres a key followed by Enter: ");
        //get a char
        ch = (char) System.in.read(); 

        //REFERRING TO THIS PART
        do{
            ignoreNewLineENTER = (char) System.in.read();
        }
        while (ignoreNewLineENTER != '\n');

} while (ch != 'q');

console input is line buffered—you have to press ENTER before characters are sent. Pressing ENTER causes a carriage return and a line feed (newline) sequence to be generated. These characters are left pending in the input buffer. Also, if you typed more than one key before pressing ENTER, they too would still be in the input buffer. This loop discards those characters by continuing to read input until the end of the line is reached. If they were not discarded, then those characters would also be sent to the program as guesses, which is not what is wanted. (To see the effect of this, you might try removing the inner do-while loop.) In Chapter 10, after you have learned more about Java, some other, higher-level ways of handling console input are described. However, the use of read( ) here gives you insight into how the foundation of Java's I/O system operates. It also shows another example of Java's loops in action.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
thordaer
  • 11
  • 2