I was working on a project for class and everything works fine until the code the professor gave us that will prompt the user to "doOver" the code if they choose to, it's coming out with this error and I'm frankly confused.
I tried changing the sc.nextLine to a .hasNextLine as I've seen in other posts, but it comes up with an error stating it needs to be a boolean and then says I can not use the next doOver.trim() code on a boolean.
final static String TITLE = "ISBN-13 Generator!";
final static String CONTINUE_PROMPT = "\nDo this again? [y/n] ";
static Scanner input = new Scanner(System.in);
private static void process(Scanner sc, String args[]) {
boolean numberChecker;
String isbn;
do {
System.out.println("\nEnter the first 12 digits of an ISBN-13: ");
isbn = input.nextLine();
input.close();
isbn = isbn.trim();
numberChecker = true;
int s = 0;
do {
numberChecker = numberChecker && Character.isDigit(isbn.charAt(s));
s++;
} while (s < isbn.length() || numberChecker == false);
} while (isbn.length() != 12 & numberChecker == false);
int sum = 0;
int s = 0;
do {
if (s % 2 == 0) {
sum = sum + isbn.charAt(s) - 48;
} else {
sum = sum + 3 * (isbn.charAt(s) - 48);
}
s++;
} while (s < 12);
{
sum = 10 - (sum % 10);
if (sum == 10)
sum = 0;
}
System.out.println("Your ISBN is " + isbn + sum);
}
private static boolean doThisAgain(Scanner sc, String prompt) {
System.out.print(prompt);
String doOver = sc.nextLine();
return doOver.trim().equalsIgnoreCase("Y");
}
public static void main(String args[]) {
System.out.println("Welcome to " + TITLE);
Scanner sc = new Scanner(System.in);
do {
process(sc, args);
} while (doThisAgain(sc, CONTINUE_PROMPT));
sc.close();
System.out.println("Thank you for using the " + TITLE);
}
It should display "Do this again? [y/n]" with you inputting "y" to start the process over and entering "n" to stop and have the system print out ("Thank you for using the " + TITLE)
This is happening because you have closed the scanner instance already using line input.close();
Just comment out or delete input.close(); and your program will work as expected.
System.out.println("\nEnter the first 12 digits of an ISBN-13: ");
isbn = input.nextLine();
//input.close();
Let me know if it helps! :)
Related
This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
My Java code should let the user enter a number and then calculate the factorial of that number and I need to use "for loop" When I enter number 5 it tells me the factorial is 6 when it should be 120. I have tried to watch tutorials with factoring loop but they wont work, i think its because i have "do" command that gets values from calling
Here is the code:
static Scanner kboard = new Scanner(System.in); //variable to read in values
public static void main(String[] args) {
int choice = 0;
String dummy = "";
String forename = "";
String surname = "";
int number = 0;
do {
System.out.println("1. display the user name, 2. calculate factorial, 3. exit");
choice = kboard.nextInt();
dummy = kboard.nextLine(); //strips out the return
if (choice == 1) {
forename = getforename();
surname = getsurname();
displaydetails(forename, surname);
}
if (choice == 2) {
number = getnumber();
calcfactorial(number);
}
if (choice == 3) {
System.out.println("bye");
}
} while (choice != 3);
}
public static String getforename() {
String newforename = "";
System.out.println("Please enter your forename ?");
newforename = kboard.next();
return (newforename);
} // end getforename
public static String getsurname() {
/*
Code to prompt the user to enter a surname
*/
String newsurname = "";
System.out.println("Please enter your surname ?");
newsurname = kboard.next();
return (newsurname);
} // end getsurname
public static void displaydetails(String displayforename, String displaysurname) {
/*
Code will carry out prescribed changes and display the result
*/
char displayinitial;
String displayusername = "";
displaysurname = displaysurname.toUpperCase();
displayinitial = displayforename.charAt(0);
displayusername = displayinitial + displaysurname;
System.out.println("Your username is " + displayusername);
}
public static int getnumber() {
System.out.println("What numbers factorial do you want to know?");
int newnumber = kboard.nextInt();
return newnumber;
}
public static void calcfactorial(int newnumber) {
int count = 0;
int factorial = 1;
if (newnumber > 0) {
for (count = 1; count <= newnumber; count++); {
factorial = factorial * count;
System.out.println("Factorial of " + newnumber + " is: " + factorial);
}
} else {
System.out.println("Number must be positive");
}
}
If you had used a debugger, then you could tell that it's only executing the multiplication in the calcfactorial method once, and count is already 6 at this point. Reasons:
First, remove the semicolon at the end of the for condition loop. It is acting as the body of the for loop. This makes count equal to newnumber + 1, or 6.
Second, move your print statement after the end of the for loop, but still within the if block. Otherwise you'll get newnumber lines of printouts.
I am not going to fully give away the answer...user azurefrog posted a helpful link on debugging code.
However, your for loop is doing something you don't intend:
public static void calcfactorial(int newnumber)
{
int count = 0;
int factorial = 1;
if (newnumber > 0)
{
for (count=1;count<=newnumber;count++);
{
factorial = factorial * count; System.out.println("Factorial of "+newnumber+" is: "+factorial);
}
}
else
{
System.out.println("Number must be positive");
}
}
Reading through this, the line factorial = factorial * count; is just going to do 1*1, 1*2, 1*3, 1*4, 1*5, etc. for whatever is entered to be calculated for factorial. This is not the correct logic.
I recommend thinking through the logic of the for loop a bit more carefully. You should be using the number entered (i.e. 5 for the example you've given) somewhere in that loop.
I'm currently working on a version of hangman through java. I've recently been stumped by a problem that I can't seem to solve.
I have an array easyDifficulty and a String hiddenWord. I want to make it so that every time the game starts, my method randomWord() will choose a random word from array easyDifficulty to start the program. Many of my methods use hiddenWord so I pasted all of my code below incase you need to check that. Otherwise, the main parts that I feel like that are causing problems are in the area where I declare my field variables, my randomWord method, and the main method.
import java.util.Arrays;
import java.util.*;
import java.util.Scanner;
public class HangmanGame {
static String[] easyDifficulty = new String[]{"orange", "jacket","shirt"
,"rocket","airplane","circle","balloon","swing","truck","caterpillar"};
static Random rand = new Random();
static String hiddenWord = new String("");
static char[] hiddenWordToChar = hiddenWord.toCharArray();
static int triesLeft = 6;
static boolean done = false;
static int length = hiddenWord.length();
static Scanner input = new Scanner(System.in);
final static int maxLength = 30;
static char[] repeatChecker = new char[30]; //this is to help prevent the user from putting the same char multiple times
static char[] fillWord = new char[length];
static int var;
static int var2;
static char underscore = '_';
static int chooseDifficultyInt;
public static String randomWord(int n) {
int randomNum = rand.nextInt(9);
int difficultyInt = n;
if (difficultyInt == 1){
//System.out.println(easyDifficulty[randomNum]);
return easyDifficulty[randomNum];
}
return null;
}
public static boolean contains(char[] arr, char i) {
for (char n : arr) {
if (i == n) {
return true;
}
}
return false;
}
public static boolean multiLetter(char[] arr, char i){
int multiple = 0;
for (char n : arr){
if (i == n){
multiple++;
//continue;
}
}
System.out.println(multiple);
if (multiple > 1){
return true;
}
else {
return false;
}
}
public static void createSpaces(int n){
for (int i = 0; i <= n-1; i++){
fillWord[i] = underscore;
}
System.out.println(fillWord);
}
public static void tryAgain(){
System.out.println("Would you like to try again? Enter Y/N to go again or quit!");
char goAgain = input.next().charAt(0);
goAgain = Character.toLowerCase(goAgain);
if (goAgain == 'y') {
triesLeft = 6;
repeatChecker = new char[20];
main(null);
}
else if (goAgain == 'n') {
System.out.println("Bye!");
System.exit(0);
}
else {
System.out.println("Invalid input");
tryAgain();
}
}
public static void arrayLetters(){
System.out.println("This is a " + length + " letter word. Please enter a letter to guess: ");
char charInput = input.next().charAt(0);
char[] letters = new char[20];
//This code only runs if the user inputs a letter that repeats
//throughout hiddenWord
if (multiLetter(hiddenWordToChar, charInput)){
for (int n = 0; n < length; n++){
char multiWordLetter = hiddenWord.charAt(n);
letters[n] = multiWordLetter;
if (letters[n] == charInput){
fillWord[n] = charInput;
}
if (contains(repeatChecker, charInput)){
System.out.println("You already did that word, try again!");
arrayLetters();
}
if (Arrays.equals(fillWord, hiddenWordToChar)){
System.out.println("Congratulations, you win! The word was '" + hiddenWord + "'!");
System.out.println("You completed the challenge in " + triesLeft + " tries! \n\n");
tryAgain();
}
}
System.out.println(fillWord);
System.out.println("Nice! There is a(n) " + charInput + " in this word!");
System.out.println("You have " + triesLeft + " tries left!\n");
arrayLetters();
}
//This block of code runs when the user input a letter that only occurs once
//in hiddenWord
for (int i = 0; i < length; i++){
char wordLetter = hiddenWord.charAt(i);
letters[i] = wordLetter;
if (contains(letters, charInput)){
/*
if (multiLetter(letters, charInput)){
System.out.println("aylmao");
}
*/
//System.out.println(multiLetter(hiddenWordArray, charInput));
if (contains(repeatChecker, charInput)){
System.out.println("You already did that word, try again!");
arrayLetters();
}
repeatChecker[var] = charInput;
var++;
fillWord[i] = charInput;
if (Arrays.equals(fillWord, hiddenWordToChar)){
System.out.println("Congratulations, you win! The word was '" + hiddenWord + "'!");
System.out.println("You completed the challenge in " + triesLeft + " tries! \n\n");
tryAgain();
}
System.out.println(fillWord);
System.out.println("Nice! There is a(n) " + charInput + " in this word!");
System.out.println("You have " + triesLeft + " tries left!\n");
arrayLetters();
}
if (i == length-1){
System.out.println("There is no " + charInput + " in this word!");
triesLeft--;
System.out.println("You have " + triesLeft + " tries left!\n");
if (triesLeft <= 0){
System.out.println("You failed!\n\n");
tryAgain();
}
arrayLetters();
}
}
}
public static void main(String[] args) {
System.out.println("Welcome to my hangman game!");
System.out.println("Please input your prefered difficulty level.");
System.out.println("1. Easy");
System.out.println("2. Medium");
System.out.println("3. Hard");
chooseDifficultyInt = input.nextInt();
randomWord(chooseDifficultyInt);
hiddenWord = randomWord(chooseDifficultyInt);
createSpaces(length);
arrayLetters();
}
}
I'm an intermediate in java programming so I've learned that Strings are immutable. Thus I've considered that the reason why hiddenWord won't be set equal to randomWord(chooseDifficultyInt); is because of that?
I'm an intermediate in java programming so I've learned that Strings are immutable
This often causes confusion among new programmers. This is correct, Strings are immutable. However the variable that points to that String can be re-assigned (assuming it isn't final).
You can modify your hidden word as many times as you like:
HangmanGame.hiddenWord = "MyNewWord";
HangmanGame.hiddenWord = "AnotherWord";
HangmanGame.hiddenWord = "ThisWorks";
You might be wondering how the hiddenWord is changing if Strings are immutable.
Your variable isn't actually changing. Every time you re-assign it, a new String is being created. This means that the Strings themselves are never modified.
So yes, you can call
HangmanGame.hiddenWord = HangmanGame.randomWord(n);
and it will work perfectly.
Your initialization of hiddenWord as new String(""); is useless. You could remove it safely.
When you do that:
hiddenWord = randomWord(chooseDifficultyInt);
you set hiddenWord to the reference of a random string of your predefined list, not allocating anything, just reusing an existing string reference.
i'll get straight to the chase. If a user wants to read another file they must type r in the menu, then they are thrown with a return readFile(); method which takes them to the top of the program and asks them the same question it did at the beggining when they first ran this program. Only issue is when you type R or Default it throws an OutOFBoundsException. BTW It is Reading a CSV file
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1000
at studentrecs.StudentRecs.in(StudentRecs.java:71)
at studentrecs.StudentRecs.readFile(StudentRecs.java:55)
at studentrecs.StudentRecs.menu(StudentRecs.java:97)
at studentrecs.StudentRecs.main(StudentRecs.java:33)
Java Result: 1
/
public static Boolean readFile(String filename) throws IOException { //Constructor for filename
try {
Scanner userInput = new Scanner(System.in);
System.out.println("Type R To Read a File or Type Default for the default file");
user = userInput.nextLine();
if (user.equalsIgnoreCase("r")) {
user = userInput.nextLine();
}
filename = user;
if (user.equalsIgnoreCase("default")) {
filename = "newreg2.csv";
}
Scanner input = new Scanner(new FileReader(filename));
while (input.hasNext()) {
in(input.nextLine());
numstu++;
}
input.close();
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
return false;
}
public static void in(String reader) {
String splitter[];
splitter = reader.split(",");
stu[numstu] = new StuRec();
stu[numstu].studentID = splitter[0];
stu[numstu].lastName = splitter[1];
stu[numstu].firstName = splitter[2];
stu[numstu].phoneNumber = splitter[3];
stu[numstu].courseCode = splitter[4];
stu[numstu].periodNumber = Integer.parseInt(splitter[5]); // parseInt turns a string of digits into an integer
stu[numstu].mark = Integer.parseInt(splitter[6]);
}
public static boolean menu() throws IOException {
String choice;
Scanner userInput = new Scanner(System.in);
System.out.println("=============================================");
System.out.println("Type R To Read Another File");
System.out.println("Type L To Print all File Records");
System.out.println("Type AA To Print The Average Of All The Marks");
System.out.println("Type X To Exit The Program");
choice = userInput.nextLine();
double average = 0.0; // declare average
if (choice.equalsIgnoreCase("L")) {
for (int i = 0; i < numstu; i++) {
System.out.println(stu[i].lastName + ", " + stu[i].firstName + ", " + stu[i].studentID + ", " + stu[i].phoneNumber + ", " + stu[i].courseCode + ", " + stu[i].periodNumber + ", " + stu[i].mark);
}
}else if (choice.equalsIgnoreCase("R")){
return readFile(filename);
} else if (choice.equalsIgnoreCase("AA")) {
for (int i = 0; i < numstu; i++) {
average += stu[i].mark; // keep adding to average
}
}else if (choice.equalsIgnoreCase("X")) {
for (int i = 0; i < numstu; i++) {
System.exit(i);
}
}else if (choice.equalsIgnoreCase("AC")) {
} else {System.err.println("Unknown Key Try Again...");
}
// divide by zero protection
if ( choice.equalsIgnoreCase("AA") && numstu > 0 ) {
average = average/numstu; // compute the average. Always use the size in terms of a variable whenever possible.
System.out.println(average); // as noted below, if this is an integer value, < #of students computations will eval to 0.
}
else if (!choice.equalsIgnoreCase("AA") && numstu < 0) {
System.out.println("Oops! No Marks To Calculate! :(");
}
return menu();
}
}
It looks like EITHER you have initialised numstu to start at 1, OR you have more than 1000 lines in your file.
The effect of either of these errors would be that you eventually attempt to write data to entry 1000 of stu. But since you've initialised stu with 1000 entries, numbered from 0 to 999, this gives your error.
You should make sure that numstu is initially 0, not 1.
And next time you post a question, post ALL of your code, not just the parts where you think the error might be. It's very difficult for most people to find bugs in code that they can't see.
I'm new to java and I have an assignment to count #s in tweets (the # has to be at the beginning of the word). Here's the code:
public static void main (String str[]) throws IOException {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a tweet.");
String tweet=scan.nextLine();
int quantity = tweet.length();
System.out.println(tweet);
if (quantity > 140)
{
System.out.println("Excess Characters: " + (quantity - 140));
}
else{
System.out.println("Length Correct");
int hashtags=0;
int v=0;
String teet=tweet;
while ((teet.indexOf('#')!=-1) || v==0){
v++;
int hashnum= teet.indexOf('#');
if ((teet.charAt(hashnum + 1)!=(' ')) && (teet.indexOf('#')!=-1)) {
hashtags++;}
teet=teet.substring(hashnum,(quantity-1));
}
System.out.println("Number of Hashtags: " + hashtags);
}
}
}
The compiler doesn't detect any errors, but when I run it, it does everything except print ("Number of Hashtags: " + hashtags). Can someone please help? Thank you.
Your while loop never exits.
Instead of
teet=teet.substring(hashnum,(quantity-1));
use
teet=teet.substring(hashnum+1,(quantity-1));
And might I humbly suggest various improvements.
public static void main (String args[]) {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter a tweet.");
String tweet = scan.nextLine();
System.out.println(tweet);
if (tweet.length() > 140) {
System.out.printf("Excess Characters: %d%n", tweet.length() - 140);
} else {
System.out.println("Length Correct");
int hashtags = tweet.length() - tweet.replaceAll("#(?=[^#\\s])", "").length();
System.out.printf("Number of Hashtags: %d%n", hashtags);
}
}
I have a question with the display array method. I can't figure how to make it to format this:
Credit Card # 4:
8908 9014 8812 1331
What I need to do is for each array element call the display method and pass the index of the array in a string for the label, I just cant figure out how to do this, I tried this but it is wrong:
System.out.println(display("Credit Card # %d", cred1[i]));
Can anyone please suggest a way to do this?
package homework4;
import java.util.Scanner;
public class Prog4 {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args)
{ CreditCardNumber[] cred1;
CreditCardNumber cred2 = getInput();
Display("The complete number from your input:", cred2);
cred1 = getInputArray();
DisplayArray(cred1);
TryAnother();
}
public static CreditCardNumber getInput() {
String ID;
String accNum;
CreditCardNumber tempCred;
System.out.printf("Please enter issuer ID:");
ID = scanner.next();
System.out.printf("Please enter account number:");
accNum = scanner.next();
tempCred = new CreditCardNumber(ID, accNum);
return tempCred;
}
public static void Display(String ch, CreditCardNumber cred2)
{
System.out.println(ch);
System.out.println(cred2.toString().replaceAll(".{4}", "$0 "));
}
public static CreditCardNumber[] getInputArray()
{
CreditCardNumber[] tempArray;
String tempID;
int size;
System.out.printf("Please enter size of the aray:");
size = scanner.nextInt();
if(size < 1)
{
size = 1;
}
tempArray = new CreditCardNumber[size];
System.out.printf("Please enter issuer ID:");
tempID = scanner.next();
System.out.print(tempArray.length);
for(int i = 0; i < tempArray.length; i++)
{
tempArray[i] = new CreditCardNumber();
tempArray[i].CreateCred(tempID);
}
return tempArray;
}
public static void DisplayArray(CreditCardNumber[] cred1)
{
for(int i = 0; i< cred1.length; i++)
{
System.out.println(display("Credit Card # %d", cred1[i]));
}
}
public static boolean TryAnother()
{
String s;
System.out.printf("Get more credit card numbers? (n for no):");
s = scanner.next();
if(s.charAt(0) != 'N' && s.charAt(0) != 'n')
{
return true;
}
return false;
}
}
sounds like all you need is a new line character. For example.
System.out.println("Credit Card # " + cred1[i] + "\n" + cred2.toString());
The new line character "\n" will drop the output onto it's own line.
Do this:
System.out.format("Credit Card # %d:\n%s", i, cred1[i].toString());