1

Absolute beginner here. I'm taking an introductory class to programming using Java and I've already fallen behind. The professor seems to just "do" in class and not really instruct. He also gives us examples to programs and then assigns programs that are far more complex than what he showed us in class.

I took it upon myself to start over and read the textbook page by page, and sure enough, many of the things I did not initially understand make sense now, and most of the programs that wouldn't work before now do.

Nevertheless, I'm stuck in the section called "Reading Keyboard Input," to be more specific, "Reading a Character." The book explains that the Scanner class does not have a method to read a single character, therefore the nextLine method is used to read a string from the keyboard, you enter a single letter, then the charAt method is used to extract the first character of the string.

The book explains it step by step, so I added the new lines to an already existing program called Payroll.java, and the original program works, but it won't let me input anything after the new lines are printed.

import java.util.Scanner;   //Needed for the Scanner class

/**
 *  This program demonstrates the Scanner class.
 */

public class Payroll{

    public static void main(String[] args){

        String name;        //To hold a name
        int hours;          //Hours worked
        double payRate;     //Hourly pay rate 
        double grossPay;    //Gross pay
        String input;       //To hold a line of input
        char answer;        //To hold a single character

        //Create a Scanner object to read input.
        Scanner keyboard = new Scanner(System.in);

        //Get the user's name.
        System.out.print("What is your name? ");
        name = keyboard.nextLine();

        //Get the number of hours worked this week.
        System.out.print("How many hours did you work this week? ");
        hours = keyboard.nextInt();

        //Get the user's hourly pay rate.
        System.out.print("What is your hourly pay rate? ");
        payRate = keyboard.nextDouble();

        //Calculate the gross pay.
        grossPay = hours * payRate;

        // Ask the user a question.
        System.out.print("Are you having fun? (Y=yes, N=no) ");
        input = keyboard.nextLine(); // Get a line of input.
        answer = input.charAt(0); // Get the first character.
    }
}

The error I get is:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String >index out of range: 0 at java.lang.String.charAt(Unknown Source) at Payroll.main(Payroll.java:39)

DVilla
  • 13
  • 1
  • 4

5 Answers5

0

Like what @asettouf said, simply using next() would work fine. However, assuming you'd like to use nextLine(), the reason it wasn't working was because the nextLine() was after a nextDouble(), which doesn't "take" the new line character, making the input to the nextLine() the new line character (or simply empty). The answer to this question provides a more thorough answer, but simply calling a new nextLine() method before attempting to get keyboard input will work. Hope this helped.

Community
  • 1
  • 1
Stephen
  • 306
  • 1
  • 3
  • 10
0

Try this:

answer = keyboard.next().charAt(0);
Mukarram Pasha
  • 278
  • 1
  • 5
  • 13
  • 1
    Hi, thanks for your reply. I forgot to mention that the lines I added at the end work perfectly fine when are executed in their own separate program. I was just trying to figure out why they wouldn't work when I added them to the existing program that I posted above. It turns out that keyboard.nextLine(); is needed to consume the newline character that was created by the nextDouble method. Cheers! – DVilla Mar 19 '17 at 22:15
0

Scanner in Java processes input in terms of tokens. In any console input, tokens are separated by whitespace. So if the input from console is hello world then we have two tokens: hello and world

The methods which process numeric inputs like nextInt() or nextDouble() do not process whitespace.
The next() method gives you the next input value in form of string. It doesn't matter whether you key-in integer or double.
The nextLine() method reads entire line and return it as string.

So after you call nextDouble() to get payRate, you have no input currently in the console since the double value is at the end of the line. So when you call nextLine(), you get an empty string in your input variable since there is nothing to process and it doesn't give the user any chance to enter anything.

Calling charAt() method on empty string causes the error.

So, what you can do is use next() method which will give the user a chance to enter input.

qrius
  • 601
  • 1
  • 7
  • 20
0

What you're looking for is something along the lines of this

answer = keyboard.nextLine().toLowerCase().charAt(0);

or, alternately

answer = keyboard.nextLine().toUpperCase().charAt(0);

Input is your scanner object that is using System.in

Scanner keyboard = new Scanner(System.in);

Then you get the "next line" which is every character until the next newline character.

answer = keyboard.nextLine()
                  ^

Then you can add in a to lowercase, or to uppercase. You'd want to do this to help with selections (I.E., want to continue? (y/n)) That way regardless of case, if the user enters y or n you get the same result.

answer = keyboard.nextLine().toLowerCase()
                             ^ Could also be .toUpperCase(), depending on what's needed

Then charAt(i) gets the character at that place in the string.

answer = keyboard.nextLine().toUpperCase().charAt(0);
                                           ^

(strings are really just objects that hold an array of characters, so in reality, you could also call .toCharArray()[0] after .toUpperCase() and get the same result).

answer = keyboard.nextLine().toUpperCase().toCharArray();

Could return an array that looks like this:

[0] => 'T', [1] => 'E', [2] => 'S', [3] => 'T'

So if desired, for short hand, or another project, you could write something like this, that would get the input, convert it to uppercase, convert it to a character array, and select one element from said array all in one line.

answer = keyboard.nextLine().toUpperCase().toCharArray()[3];

Would return the 3rd character in the array, and the following line would be equivalent.

answer = keyboard.nextLine().toUpperCase().charAt(3);

Then you can assign the result (which at this point should be one upper, or lowercase character, depending on which method you used in the middle) to a character variable, to be used in loops or what have you. I know this explanation is a bit verbose, but hopefully this can prevent some problems for you in the future.

user1631686
  • 19
  • 1
  • 1
  • 4
  • Hello. Thank you for taking the time to reply. I had forgotten to mention that the lines I added at the end work fine when they are executed in their own separate program. My issue was getting them to work in the program I posted above. The issue was that the input = keyboard.nextLine(); was reading the whitespace (my textbook calls this a "newline character") that was created by the nextDouble method. adding the line keyboard.nextLine(); after grossPay=hours*payRate; solved the issue. – DVilla Mar 19 '17 at 22:26
0

just put

keyboard.nextLine();

after grossPay=hours*payRate;

to consume the empty white space that you created at

payRate = keyboard.nextDouble();
tanginaMoBobo
  • 514
  • 1
  • 5
  • 13
  • Yes, thank you! Had I bothered to continue reading the text, I would've realized that it explained this error in the next few paragraphs. I let my frustration and impatience get the best of me and decided to seek help instead. Nevertheless, this is exactly what was causing the error. According to the text: >Because the nextDouble method, back in line 24, left a newline >character in the keyboard buffer, the nextLine method will not read any >input. Instead, it will immediately terminate, and the user will not be >given a chance to enter his or her name. – DVilla Mar 19 '17 at 21:54