Can't get out of my while loop - java

I was wondering if someone can tell me why my while loop is acting funny. When I input a 3 word phrase it should create an acronym. For a reason beyond my java understanding the while loop executes but then keeps executing even when the client inputs the right answer. Any idea why? I have read what seems million posts and watch youtube videos about it, but no clue.
import javax.swing.*;
import java.util.*;
public class ThreeLetterAcronym
{
public static void main(String args[])
{
//variables
String phrase;
int wordCount;
String acronym;
//input
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase.");
String [] word = phrase.split("\\s+");
wordCount = word.length;
//loop for error when less than 3 words
do
{
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
+ "Please try again.");
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");
}
while(wordCount !=3);
//create acronym
acronym = Character.toString(word[0].charAt(0)).toUpperCase() +
Character.toString(word[1].charAt(0)).toUpperCase() +
Character.toString(word[2].charAt(0)).toUpperCase();
//output
JOptionPane.showMessageDialog(null, "The phrase you inputed is " + "."
+ phrase + "\nYour 3 letter acronym is " + acronym + ".");
}
}
enter code here

Your loop will fail if the user types 4 or more words. Change wordCount != 3 to wordCount < 3 or be ready to handle longer phrases like North Atlantic Treaty Organization.
A do-while loop always executes at least once. Here, where you are checking for errors, that's actually reasonable, but you are also never recalculating your word array, so the error condition persists. You want logic like:
String[] words; // words, not word. There is more than one.
while (true) {
// 1. Fill in the word array from the user's input.
// 2. Check the input for errors.
// a. If there are none, break out of the loop with a break statement.
// b. Otherwise, show the error message.
}
// Create the acronym. Try to use a loop for this too, as in:
StringBuilder acronym = new StringBuilder();
for (String word: words) {
// Append to acronym.
}
// report acronym.
Finally, try not to do all your work in main. Create a ThreeLetterAcronym object, give it instance variables and methods, and tell it to do the work. Break up the work in main into smaller methods. Now, you can test those methods.

Your loop is executing after entering a three-word phrase because, as Eric mentioned, a 'do-while' loop will always execute at least once. The best, simple solution to resolve that issue would be to use a while loop instead, as follows:
while(wordCount != 3)
{
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");enter code here
}
A do-while loop performs an action and then checks if it should perform that action again. A while loop checks if it should perform an action first, which is what you want to be doing.
There are also some other significant issues that would be worth resolving at the same time.
Your variables word and wordCount are not being updated once the program enters your do-while loop. If a user first enters a three-word phrase, they're fine. If they enter a phrase of any other length the program will loop indefinitely. Since the program is executing the logic inside the do-while loop only, and that does not include saving new words into the variable word or figuring their length an dstoring it in wordCount, there is no way to exit the loop.
As a quick fix I added these two lines to solve those issues:
word = phrase.split("\\s+");
wordCount = word.length;
You could also eliminate the wordCount variable entirely by checking, but I'm honestly not sure if there's value in doing that versus having the variable in use. phrase.split("\\s+").length in the while loop.

Your main problem is that your loop will never terminate; wordCount is not being updated inside of your do...while block.
Your next problem is that a do...while loop always runs at least once.
What you can do to fix this issue is move another instantiation of word into your loop body, remove the unnecessary wordCount variable (since it's a property of the array, and we only need it in one spot), and change your do...while to a while.
//input
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase.");
String[] word = phrase.split("\\s+");
//loop for error when less than 3 words
while(word.length < 3) {
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
+ "Please try again.");
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");
word = phrase.split("\\s+");
}

Solved
use this code -
import javax.swing.*;
public class ThreeLetterAcronym
{
public static void main(String args[])
{
//variables
String phrase;
int wordCount;
String acronym;
//input
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase.");
String [] word = phrase.split(" ");
wordCount = word.length;
//loop for error when other than 3 words
while(wordCount!=3)
{
JOptionPane.showMessageDialog(null, "Error, you need to input a 3 word phrase to create a 3 letter acronym." + '\n'
+ "Please try again.");
phrase = JOptionPane.showInputDialog(null, "Please enter a three word phrase");
}
//create acronym
acronym = Character.toString(word[0].charAt(0)).toUpperCase() +
Character.toString(word[1].charAt(0)).toUpperCase() +
Character.toString(word[2].charAt(0)).toUpperCase();
//output
JOptionPane.showMessageDialog(null, "The phrase you inputed is " + "."
+ phrase + "\nYour 3 letter acronym is " + acronym + ".");
}
}

Related

How to repeatedly enter a string until user enters keyword to stop loop in java

I am stuck in this program that is string method, my issue is that I cannot get the loop to stop and the program to print the output that is currently stored after the keyword has been entered. I am not trying to compare strings, I am trying to input multiple strings and add a word, in this case, "not" to the strings until the word "stop" is entered. Once "stop" has been entered. the system will output the entire string stored.
Here is the question for the program:
(StringConcat.java) This program asks the user to repeatedly enter a String. It ,should concatenate those Strings together, but insert spaces and the word “not” between every pair of words the user enters. Stop when the user enters the String “stop”. Display the final String. For instance, the program output might look like:
Please enter some Strings:
"Such"
"eyes"
"you"
"have"
"stop"
"Such not eyes not you not have"
Here is my code so far:
import java.util.*;
public class StringConcat{
public static void main(String [] args){
Scanner sc = new Scanner(System.in);
String s = new String();
System.out.print("Please enter some Strings: ");
for(int x=0; x<s.length(); x++){
s = sc.nextLine();
s = s + "not ";
if(s == "stop"){
System.out.println(s);
break;
}
else{
continue;
}
}
}
}
Several issues with your code:
(1) Why do you use a for loop and iterate up to s.length() when the length of s (which is 0 at that point) has nothing to do with your problem?
You need a loop which has not predefined number of iterations like a while (true) from which you will exit with a break.
(2) In each iteration you get the user's input and store it in s, so you lose all previous values.
You need a separate variable to store the user's input.
(3) The continue statement is not needed as the last statement in a loop.
(4) Because at each iteration you append " not " at the end, after the loop has finished you must delete that last " not " from s
(5) Don't use == when you compare strings. There is the method equals() for this.
This is my solution:
Scanner sc = new Scanner(System.in);
String s = "";
System.out.print("Please enter some Strings: ");
while (true){
String input = sc.nextLine();
if(input.equalsIgnoreCase("stop"))
break;
s += input + " not ";
}
if (s.length() >= 5)
s = s.substring(0, s.length() - 5);
System.out.println(s);
Use while loop.
Why while loop?
Usually we have to use while loops always when we don't know the number of loops we will do. In this case only when the user inputs "stop".
So you need a String field to hold the user words. Also we can use a number field to track if is the first or the second word, thinkg in append the "not" word.
Then, take a look in this example:
Scanner s = new Scanner(System.in);
String currentAnswer = "";
String userWords = "";
int tracker = 0;
while (!currentAnswer.equals("stop")){
currentAnswer = s.nextLine();
userWords += currentAnswer + " ";
if (tracker % 2 != 0) {
userWords += "not ";
}
tracker++;
}
System.put.println(userWords);
This can be done using for loop too but I really recommend the while loop to this case.
EDIT:
As you saw, I used equals() instead == to compare two Strings because we are wiling to check for its value, not for its object equality.
When we use == operator we are trying to check if two objects target to the same memory adress, but we only want to know if two Strings have the same value.
For this case is valid to know that we can compare it using other ways, such as Objects.equals() or even contentEquals().
Check this discussion to learn more about comparing strings.

Easy fix for while loop not executing properly second time?

I'm fairly new at java and have a current assignment to take a given word, put the first word at the end, rebuild the word from reverse, and see if it's the same word as the original, such as: grammar, potato, uneven, dresser, banana etc. So far I have this:
Scanner input = new Scanner(System.in);
String original, reverse = "";
String exit = "quit";
int index;
System.out.println("Please enter a word (enter quit to exit the program): ");
original = input.next();
while (!original.equalsIgnoreCase(exit))
{
String endingChar = original.substring(0, 1);
String addingPhrase = original.substring(1);
reverse += endingChar;
for (index = addingPhrase.length() - 1; index >= 0; --index)
{
char ch = addingPhrase.charAt(index);
reverse += ch;
}
if (original.equals(reverse))
{
System.out.println("Success! The word you entered does have the gramatic property.");
}
else
{
System.out.println("The word you entered does not have the gramatic property."
+ " Please try again with another word (enter quit to exit the program): ");
}
original = input.next();
}
input.close();
When I run it and enter the word "banana," it properly recognizes that it is indeed the same backwards when the b is moved to the end, and does the same with the other words listed above, but when I enter a second word on the loop, it never recognizes it properly, and always responds with the print statement from the else block:
Please enter a word (enter quit to exit the program):
banana
Success! The word you entered does have the gramatic property.
banana
The word you entered does not have the gramatic property. Please try again
with another word (enter quit to exit the program):
I'm guessing it's something to do with either the way I made my for loop, or the way I asked for input at the end of the while loop, but like I said I'm fairly new and awful at debugging. Any help would be much appreciated, thanks a lot in advance.
You are changing string reverse in every iteration, but you are not clearing it. So before the end of the loop or at the beginning clear the string for example like so: reverse = "", and then it should be fine.
Just add reverse = ""; in the end of the while loop in order to set the variable reverse to its original state, i.e. empty string

print even words from string input?

I am in a beginners course but am having difficulty with the approach for the following question: Write a program that asks the user to enter a line of input. The program should then display a line containing only the even numbered words.
For example, if the user entered
I had a dream that Jake ate a blue frog,
The output should be
had dream Jake a frog
I am not sure what method to use to solve this. I began with the following, but I know that will simply return the entire input:
import java.util.Scanner;
public class HW2Q1
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a sentence");
String sentence = keyboard.next();
System.out.println();
System.out.println(sentence);
}
}
I dont want to give away the answer to the question (for the test, not here), but I suggest you look into
String.Split()
From there you would need to iterate through the results and combine in another string for output. Hope that helps.
While there will be more simpler and easier way to do this, I'll use the basic structure- for loop, if block and a while loop to achieve it. I hope you will be able to crack the code. Try running it and let me know if there is an error.
String newsent;
int i;
//declare these 2 variables
sentence.trim(); //this is important as our program runs on space
for(i=0;i<sentence.length;i++) //to skip the odd words
{
if(sentence.charAt(i)=" " && sentence.charAt(i+1)!=" ") //enters when a space is encountered after every odd word
{
i++;
while(i<sentence.length && sentence.charAt(i)!=" ") //adds the even word to the string newsent letter by letter unless a space is encountered
{
newsent=newsent + sentence.charAt(i);
i++;
}
newsent=newsent+" "; //add space at the end of even word added to the newsent
}
}
System.out.println(newsent.trim());
// removes the extra space at the end and prints newsent
you should use sentence.split(regex) the regular expression is going to describe what separate your worlds , in your case it is white space (' ') so the regex is going to be like this:
regex="[ ]+";
the [ ] means that a space will separate your words the + means that it can be a single or multiple successive white space (ie one space or more)
your code might look like this
Scanner sc= new Scanner(System.in);
String line=sc.nextLine();
String[] chunks=line.split("[ ]+");
String finalresult="";
int l=chunks.length/2;
for(int i=0;i<=l;i++){
finalresult+=chunks[i*2]+" ";//means finalresult= finalresult+chunks[i*2]+" "
}
System.out.println(finalresult);
Since you said you are a beginner, I'm going to try and use simple methods.
You could use the indexOf() method to find the indices of spaces. Then, using a while loop for the length of the sentence, go through the sentence adding every even word. To determine an even word, create an integer and add 1 to it for every iteration of the while loop. Use (integer you made)%2==0 to determine whether you are on an even or odd iteration. Concatenate the word on every even iteration (using an if statement).
If you get something like Index out of range -1, manipulate the input string by adding a space to the end.
Remember to structure the loop such that, regardless of the whether it is an even or odd iteration, the counter increases by 1.
You could alternatively remove the odd words instead of concatenation the even words, but that would be more difficult.
Not sure how you want to handle things like multiple spaces between words or weird non-alphabetically characters in the entry but this should take care of the main use case:
import java.util.Scanner;
public class HW2Q1 {
public static void main(String[] args)
{
System.out.println("Enter a sentence");
// get input and convert it to a list
Scanner keyboard = new Scanner(System.in);
String sentence = keyboard.nextLine();
String[] sentenceList = sentence.split(" ");
// iterate through the list and write elements with odd indices to a String
String returnVal = new String();
for (int i = 1; i < sentenceList.length; i+=2) {
returnVal += sentenceList[i] + " ";
}
// print the string to the console, and remove trailing whitespace.
System.out.println(returnVal.trim());
}
}

Scanner & .hasNext() issue

I am new to Java and very new to the Scanner class. I am writing a program which asks the user for a word and then this word is searched for within a file. Each time the word is found, it is printed on a new line in a JOptionPane, as well as the word before and after it. Everything is functioning as it should, with two exceptions:
If the word being searched for happens to be the last word in the file then a "NoSuchElementException" is thrown.
If the word being searched for appears twice in a row (unlikely, but still a problem I discovered), it only returns it once. For example, if the word being searched for was "had" and "He said that he had had enough. He had been up all night" were sentences in the file, then the output is:
he had had
He had been
whereas it should be:
he had had
had had enough.
He had been
I believe that my problem lies in the fact that I use a while(scan.hasNext()) and within this loop I use scan.next() twice. I cannot find a solution for this though, while still achieving what I would like the program to return.
Here is my code:
//WordSearch.java
/*
* Program which asks the user to enter a filename followed
* by a word to search for within the file. The program then
* returns every occurrence of this word as well as the
* previous and next word it appear with. Each of these
* occurrences are printed on a new line when displayed
* to the user.
*/
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class WordSearch {
public static void main(String[] args) throws FileNotFoundException {
String fileName = JOptionPane.showInputDialog("Enter the name of the file to be searched:");
FileReader reader = new FileReader(fileName);
String searchWord = JOptionPane.showInputDialog("Enter the word to be searched for in \"" + fileName + "\":");
Scanner scan = new Scanner(reader);
int occurrenceNum = 0;
ArrayList<String> occurrenceList = new ArrayList<String>();
String word = "", previousWord, nextWord = "", message = "", occurrence, allOccurrences = "";
while(scan.hasNext()){
previousWord = word;
word = scan.next();
if(word.equalsIgnoreCase(searchWord)){
nextWord = scan.next();
if(previousWord.equals("")){
message = word + " is the first word of the file.\nHere are the occurrences of it:\n\n";
occurrence = word + " " + nextWord;
}
else{
occurrence = previousWord + " " + word + " " + nextWord;
}
occurrenceNum++;
occurrenceList.add(occurrence);
}
}
for(int i = 0; i < occurrenceNum; i++){
allOccurrences += occurrenceList.get(i) + "\n";
}
JOptionPane.showMessageDialog(null, message + allOccurrences);
scan.close();
}
}
Also, on a side note: How can I implement scan.useDelimeter() to ignore any, question marks, commas, periods, apostrophes etc?
If the word being searched for happens to be the last word in the file then a NoSuchElementException is thrown.
This is because of this line:
if(word.equalsIgnoreCase(searchWord)) {
nextWord = scan.next();
...
}
You do not check if the scan actually hasNext(), going straight for scan.next(). You can fix this by adding a conditional with a call to scan.hasNext()
If the word being searched for appears twice in a row (unlikely, but still a problem I discovered), it only returns it once.
That the same problem is in play here: when you find a word, you retrieve the next one right away.
Fixing this is a little tricky: you need to change your algorithm to look at one word at a time, and use previousWord (which you store anyway) for use of subsequent iterations of the while loop.
What you could do is just call hasNext before using next again.
while(scan.hasNext()){
previousWord = word;
word = scan.next();
if(word.equalsIgnoreCase(searchWord) && scan.hasNext()){ // this line change
nextWord = scan.next();
if(previousWord.equals("")){
message = word + " is the first word of the file.\nHere are the occurrences of it:\n\n";
occurrence = word + " " + nextWord;
}
else {
occurrence = previousWord + " " + word + " " + nextWord;
}
occurrenceNum++;
occurrenceList.add(occurrence);
}
}
You want to not use equals with ignore case. You want to just use .equals().
The solution would be to save two words the way you are currently saving previousWord. Something like:
while (scan.hasNext()) {
previousWord = word;
word = nextWord;
nextWord = scan.next();
Then you check word. If it matches what you need, then you can print it together with previousWord and nextWord. That is, in every iteration, you are checking the word you read in the previous iteration.
This way you only need one hasNext() and one next() in your loop.
Note that after the end of the loop, nextWord might actually be your word. This would mean your word is the last word in the file, and you should check for this and print it accordingly.

Adding Spaces between words and making every word except the first lowercase in java

I'll go ahead and let you know that yes, this is homework. I have hit a brick wall in completing it however and desperately need help. I'm also pretty new to Java and am still learning the language.
Okay, I am trying to write a program that asks the user to enter a sentence with no spaces but have them capitalize the first letter of each word. The program should then add spaces between the words and have only the first word capitalized, the rest should start with a lowercase. I can get the space inserted between the words, but I cannot get the first letter of each word lower-cased. I have tried several different ways, and the latest one is giving me this error message:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String ind
ex out of range: 72
at java.lang.AbstractStringBuilder.setCharAt(Unknown Source)
at java.lang.StringBuilder.setCharAt(Unknown Source)
at renfroKristinCh9PC14.main(renfroKristinCh9PC14.java:45)
I'm posting up my code and any and all help you can give me will be very much appreciated.
Thanks.
/*
This program will ask the user to enter a sentence without whitespaces, but
with the first letter of each word capitilized. It will then separate the words
and have only the first word of the sentence capitalized.
*/
import java.util.*;
public class renfroKristinCh9PC14
{
public static void main(String[] args)
{
//a string variable to hold the user's input and a variable to hold the modified sentence
String input = "";
//variable to hold a character
char index;
//create an instance of the scanner class for input
Scanner keyboard = new Scanner(System.in);
//welcome the user and explain the program
userWelcome();
//get the sentence from the user
System.out.println("\n Please enter a sentence without spaces but with the\n");
System.out.println(" first letter of each word capitalized.\n");
System.out.print(" Example: BatmanIsTheBestSuperheroEver! ");
input = keyboard.nextLine();
//create an instance of the StringBuilder class
StringBuilder sentence = new StringBuilder(input);
//add spaces between the words
for(int i=0; i < sentence.length(); i++)
{
index = sentence.charAt(i);
if(i != 0 && Character.isUpperCase(index))
{
sentence.setCharAt(index, Character.toLowerCase(index));
sentence.append(' ');
}
sentence.append(index);
}
//show the new sentence to the user
System.out.println("\n\n Your sentence is now: "+sentence);
}
/*********************************************************************************** *************************
************************************************************************************ *************************
This function welcomes the user and exlains the program
*/
public static void userWelcome()
{
System.out.println("\n\n **************** ****************************************************\n");
System.out.println(" * Welcome to the Word Seperator Program *");
System.out.println(" * This application will ask you to enter a sentence without *");
System.out.println(" * spaces but with each word capitalized, and will then alter the *");
System.out.println(" * sentence so that there arespaces between each word and *");
System.out.println(" * only the first word of the sentence is capitalized *");
System.out.println("\n ********************************************************************\n");
}
}
You are appending to the same string that you are iterating through. Instead, just make your sentence an empty StringBuilder. Then you can append to that while iterating through input. For example:
StringBuilder sentence = new StringBuilder();
//add spaces between the words
for(int i=0; i < input.length(); i++)
{
char letter = input.charAt(i);
if(i != 0 && Character.isUpperCase(letter))
{
sentence.append(' ');
sentence.append(Character.toLowerCase(letter));
}
else
{
sentence.append(letter);
}
}
(Note that I've changed the variable name from index to letter, which is a lot less confusing.)
You have a few different problems here. The main one is that when you call
sentence.setCharAt(index, Character.toLowerCase(index));
you're passing in the actual character in as the first argument, instead of the position. You see, you've just done
index = sentence.charAt(i);
so index is the character itself. Java implicitly converts this character to an integer - but it's not the integer that you want it to be. You probably should have written
sentence.setCharAt(i, Character.toLowerCase(index));
instead.
Also, your sentence.append(' '); will append the space to the end of the StringBuilder, rather than inserting it where you want it to.
And your final sentence.append(index); will duplicate the character. I really don't think you want to do this.

Categories

Resources