Java for loop isn't terminating in my code - java

For some reason my for loop is not terminating in my CapitalizeFirstSentence method. I set a breakpoint at that line and the condition (i != -1) is unmet, so the loop should terminate, but it doesn't!
It works when I use (i > 0) for the condition.
I'm not sure what's going on here.
import javax.swing.JOptionPane;
public class SentenceCapitalizer {
//Main Method
public static void main(String[] args) {
String input; //creates a String to hold keyboard input
//Prompt the user to enter a String using JOptionPane and set it equal to input
input = JOptionPane.showInputDialog("Enter a string. ");
//Display the new String with the first letter of each sentenced capitalized
JOptionPane.showMessageDialog(null, CapitalizeFirstSentence(input));
//Exit the program
System.exit(0);
}
//Capitalize first letter of each sentence
public static String CapitalizeFirstSentence(String in)
{
//Creates a StringBuilder object initiralized to the String argument "in"
StringBuilder temp = new StringBuilder(in);
//Capitalize first letter of the string if string length is > 0
if (temp.length() > 0)
{
temp.setCharAt(0, Character.toUpperCase(temp.charAt(0)));
}
//sets i equal to index of the space,
//keep capitalizing first letters of each sentence (loops each time it capitlizes a letter)
//until very end of the String
for (int i = temp.indexOf(". ")+1; i != -1; i++)
{
//Checks for extra spaces and moves index to first character of next sentence
while (i < temp.length() && temp.charAt(i) == ' ')
{
i++;
}
//Capitalize character
temp.setCharAt(i, Character.toUpperCase(temp.charAt(i)));
//Index the end of the sentence
i = temp.indexOf(". ", i);
}
//Convert temp to a String and return our new first-sentenced-capitalized String
return temp.toString();
}
}

First, it is not a good idea to modify the loop-controlling variable inside a for loop - it is quite hard to read and understand such code, and is prone to errors.
Now, to your example:
for (int i = temp.indexOf(". ")+1; i != -1; i++)
This means:
Initialize i to temp.indexOf(". ")+1, which is always >= 0
Terminate if i == -1
After each iteration, increment i by 1
So:
At the start, the cycle won't terminate because the initialization always returns >= 0
Each iteration, the loop body will set i = temp.indexOf(". ", i);, which is >= -1
After each iteration, i will be incremented by 1, so it will now be >= 0
As i is always >= 0, it will never meet the condition i == -1 and thus will never terminate

This line: for (int i = temp.indexOf(". ")+1; i != -1; i++) initializes i to be the result of indexOf + 1. IndexOf gives -1 if there is no hit, but you always add 1 to that during initialization, so it'll never be smaller than 0.
Using i > 0 seems perfectly fine there.

Related

java Index 5 out of bounds for length 5 error while doing while loop

I'm trying to switch every odd index character with the nearest even index character to it in a string.
public class A3_Q1 {
public static void main(String... args) {
System.out.print("Enter the messgae you want to be coded: ");
Scanner in = new Scanner(System.in);
String msg = in.nextLine();
in.close();
msg = msg.trim();
char msg1[] = msg.toCharArray();
int index = 0;
while (index<msg.length()) {
msg1[index] = msg1[++index];
index++;
}
System.out.print(msg1);
}
}
I tried searching and asking more experienced friends what's wrong but we don't know bare with us all compsci freshmen
What happens if index is msg.length() -1? You will be out-of-range.
So you should check two condition in your loop.
index is odd or even
index and index + 1 is not out-of-bound msg.length.
++index increments the index first before using the value.
index++ uses the value first before incrementing.
That means each iteration increments index by 2.
If msg has an odd length (your example 5) and index = 4 you enter the loop.
[++index] is evaluated to [5] and you get the exception.
So you have to ignore the last character for odd lenths with while (index<msg.length() - 1)
public static void main(String... args) {
// Best practice: one instruction per one line
System.out.print("Enter the message you want to be coded: ");
// When using System.in you should not close the Scanner
Scanner scan = new Scanner(System.in);
String message = scan.nextLine().trim();
// Best practice: move encoding logic to the separate method
String convertedMessage = convert(message);
System.out.println(convertedMessage);
}
public static String convert(String str) {
// String is immutable, so we have to use StringBuilder to build a new string
StringBuilder buf = new StringBuilder();
// does not matter what to use, I prefer for...loop
for (int i = 0; i < str.length(); i++) {
// do not forget to check case for the last index
if (i == str.length() - 1 || i % 2 != 0)
buf.append(str.charAt(i));
else
// here we have odd and not last index (just use the next one)
buf.append(str.charAt(i + 1));
}
return buf.toString();
}
Demo
Enter the message you want to be coded: abcdefghijklmnopqrstuvwxyz
bbddffhhjjllnnpprrttvvxxzz
It will out of bounds because:
while (index<msg.length()) {
msg1[index] = msg1[++index];
index++;
}
java index start with 0. So if the lengh is 5 it will be 0, 1, 2, 3, 4.
msg1[index] = msg1[++index];
On this line with index 4 you will out of bounds because 4+1 is 5.
you need to add something like this
if(++index<msg.length())

Why won't my program terminate when i input END?

I am trying to terminate my code when "END" is input into the console, however my code wont play fair and I can't seem to see where it is going wrong, btw I haven't learnt how to debug as of yet so this has largely got to do with why i can't figure it out. please do help if you can.
import java.util.*;
class Main
{
public static void main(String args[])
{
int j = 0;
while (j++ <= 3) {
// Create Scanner object to take input from command prompt
Scanner s=new Scanner(System.in);
// Take input from the user and store it in st
String st = "";
while (!st.equals("END")) {
{
st=s.nextLine();
// Initialize the variable count to 0
int count=0;
// Convert String st to char array
char[] c=st.toCharArray();
// Loop till end of string
for(int i=0;i<st.length();i++)
// If character at index 'i' is not a space, then increment count
if(c[i]!=' ') count++;
// Print no.of spaces
System.out.printf("[%4d] spaces in ", +(st.length()-count));
// Print no.of spaces
System.out.println('"' + st + '"');
}
j++;
}
}
}
Since you have while (j++ <= 3) { ... } your program will end if you enter "END" two times.
Because you have two while loops nested. You input "END" in the second while loop and after that the second loop ends that's correct. But as you see, after it ends it will start the first loop which is while (j++ <= 3) { and in this while loop it waits for an input from user 3 times, which corresponds to Scanner s=new Scanner(System.in);, therefore it is normal for your program not to exit. If you want your program to finish after some input you may want to use System.exit(-1); command. I've added code according to your comments.
import java.util.*;
class Main {
public static void main(String args[]) {
int j = 0;
while (j++ <= 3) {
// Create Scanner object to take input from command prompt
Scanner s = new Scanner(System.in);
// Take input from the user and store it in st
String st = s.nextLine();
if (!st.equals("END")) {
// Initialize the variable count to 0
int count = 0;
// Convert String st to char array
char[] c = st.toCharArray();
// Loop till end of string
for (int i = 0; i < st.length(); i++)
// If character at index 'i' is not a space, then increment count
{
if (c[i] != ' ') {
count++;
}
}
// Print no.of spaces
System.out.printf("[%4d] spaces in ", +(st.length() - count));
// Print no.of spaces
System.out.println('"' + st + '"');
} else {
System.exit(-1);
}
}
}
}
I have just add an if condition without using loop.
public static void main(String args[]) {
int j = 0;
while (j++ <= 3) {
// Create Scanner object to take input from command prompt
Scanner s = new Scanner(System.in);
// Take input from the user and store it in st
String st = "";
st = s.nextLine();
if (st.equalsIgnoreCase("END")) {
j = 5;
}
// Initialize the variable count to 0
int count = 0;
// Convert String st to char array
char[] c = st.toCharArray();
// Loop till end of string
for (int i = 0; i < st.length(); i++) // If character at index 'i' is not a space, then increment count
{
if (c[i] != ' ') {
count++;
}
}
// Print no.of spaces
System.out.printf("[%4d] spaces in ", +(st.length() - count));
// Print no.of spaces
System.out.println('"' + st + '"');
j++;
}
}
What I do basically when I get the input end I just change the value of j to 5 so that the first loop will be terminated. and stop taking inpu.
Do you want this type of solution or you want you need to take input 3 times?

My variable may not have been Initialized

So I think my while loop is not even occurring and I am not quite sure why. It is probably an something obvious however I cannot seem to find the solution. What this code is attempting to do is use the variable "firstLetter" and add to the String "passcode" and continue to add the different characters that are specified within the while loop. however it is saying that my variable may have not been initialized which makes me think that the whole loop is messed up and is not being seen. Im pretty new to coding so any help would be appreciated
import java.util.Scanner;
public class Password
{
public static void main (String [] args)
{
System.out.println("This program will take a phrase by you and"
+ "\ncreate a strong and safe password that "
+ "\nwill be similar. Please enter a phrase.");
Scanner keyboard = new Scanner (System.in);
String message = keyboard.nextLine();
String firstLetter;
int index = 0,
number = 0, //a counting mechanism
spot = 2, // how many characters in each word you put down
pass = 1; //counting up the number of char in the password
if (message.charAt(0) == ' '){
System.out.println("Make sure the first character in your "
+ "phrase is not a space");
System.exit(1);
}//if
System.out.print("\nYour Password is: ");
char white = message.charAt(index);
firstLetter = Character.toString(white);
System.out.println(firstLetter);
index = 1;
String passcode;
while(index < message.length()) {
white = message.charAt(index);
if ((white != ' ') && (number != spot)) {
pass = pass + 1;
index = index + 1;
number = number + 1;
passcode = firstLetter + white;
}//if
else if (white != ' ') {
index = index + 1;
}//else if
else { spot = spot + 1;
number = 0;
index = index + 1;
}//else
}//while
System.out.print(passcode);
}
}
You have declared a variable passcode like:
String passcode;
The only way to initialize it when you go in while loop (meaning while condition satisfies), you go into if if ((white != ' ') && (number != spot)) { What if it doesn't satisfies condition? That means you dont have any values for pass code and then you try to access it like:
System.out.print(passcode);
Hence compiler complains about the same. So you need to do something addition to String declaration like:
String passcode = "";//define it as well with default value and you might need to check defining values within if/else where its not already present
Just had a brief look at the code, I feel this would not compile and complain about passcode variable not being initialized. What if the condition
index < message.length() is not true first time and while loop is never entered!!
I guess that explains why compiler is giving error.
You can initialize passcode to any value, null or empty string may be depending on your use case which I am not sure of.
Hope this helps.

Restarting While Loop after false boolean in Java

I'm doing an assignment for school that requires us to find the largest of ten numbers. The numbers are between 0-9. I believe I got that part down. My problem is I'm trying to add an extra feature that is not required for the assignment. I am trying to get the loop to completely restart after the boolean statement is false and gives an error message. After I type the invalid value in, it gives the error message, but after I press "ok" it continues on to the next number. I want it to start back at the beginning of the loop.
Here's the code:
package Largest;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class LargestMain {
public static void main(String[] args) {
int number = 0;
String numStr = "";
int []myArray = new int[10];
int count = 1;
int largest = 0;
boolean valid = false;
while(valid == true); { // Loop to check validity
for(int i = 0; i < myArray.length; i++) {
myArray[i] = i + 1;
numStr = JOptionPane.showInputDialog("Please enter number " + count++ + ":");
number = Integer.parseInt(numStr); // Converts string value to integer
if(number >= largest) {
largest = number;
}
// If-Else if statements checks if values entered are equal to 0-9
if(number >= 0 && number <= 9) {
valid = true;
}
else if ((!(number >= 0 && number <= 9))) {
valid = false;
}
if (valid == false) {
JOptionPane.showMessageDialog(null, "INVALID INPUT...Try Again!!!", "Results", JOptionPane.YES_OPTION);
continue;
}
}
JOptionPane.showMessageDialog(null, "The Largest Number Is: " + largest, "Results", JOptionPane.PLAIN_MESSAGE);
}
}
}
I could just end the loop here by adding return:
if (valid == false) {
JOptionPane.showMessageDialog(null, "INVALID INPUT...Try Again!!!", "Results", JOptionPane.YES_OPTION);
return;
}
I just really want to learn how to restart the loop from the beginning. I tried search different topics, but none helped me solve my problem. Thanks for the help in advance!
To restart a loop, you would use the continue keyword. continue will skip to the next loop iteration.
When using a while loop, it'll simply restart the loop, since the loop doesn't end til valid is true. When using a for loop, itll skip to the next iteration (so if you're currently on index 5 and use continue, it'll move onto index 6 instead of staying at 5).
For nested loops, you can label the loop to specify which loop the statement is for:
firstloop:
while(valid) {
secondloop:
while(true) {
continue firstloop;
}
}
Also, no need for == true when checking a boolean. It could be represented as
while(valid) {
}
As for checking for false, valid == false, you'd use
while(!valid) {
}
Since you're a beginner and trying to learn, I have done a review of your code and enclosed some comments that might help you. I have posted updated code below.
Declarations: You should declare a variable in the innermost closure that requires it. Except largest, all other can go inside the for.
Your array variable did not make sense to have. Since you're keeping track of the largest as you go and not finding it at the end.
Control: Your /loop to check validity/ needs to be strictly around the input part, not your whole program, so you can repeat just the input statements till you're satisfied.
public static void main(String[] args)
{
int largest = 0;
for(int i = 1; i <= 10; i++)
{
boolean valid = false;
while (!valid)
{
String numStr = JOptionPane.showInputDialog("Please enter number " + i + ":");
int number = Integer.parseInt(numStr); //Converts string value to integer
if (number >= 0 && number <= 9)
{
valid = true;
}
else
{
JOptionPane.showMessageDialog(null, "INVALID INPUT...Try Again!!!", "Results", JOptionPane.YES_OPTION);
}
}
if (number > largest)
{
largest = number;
}
}
JOptionPane.showMessageDialog(null, "The Largest Number Is: " + largest, "Results", JOptionPane.PLAIN_MESSAGE);
}
You can use a labeled continue:
firstloop:
while(valid){
secondloop:
for(int i=0; i<10; i++{
//something
if(something){
continue firstloop;
}
}
}
See the documentation for more details.
UPDATE: Also... there is no need for the condition in the else part of your if/else statement. Just doing a else{ valid=false } would be equivalent to what you're doing right now. Another option would be to simplify it even further and skip the if/else part alltogether and just have:
valid = number >= 0 && number <= 9
Write a recursive function, that is, a function that calls itself.
public static void DoSomething()
{
// optionally ask the user for input at this point before processing begins.
while(yourCondition)
{
// do your stuff.
}
// when execution reaches here the condition is no longer valid; start over.
if(conditionToStartOver)
DoSomething(); // start again
}
Your logic is almost right but you shouldn't be looping on valid in the outer loop. Remember, you want to stop the inner loop when an input is invalid. Normally the outer loop would give the user an option to exit the program.
So for example:
while(true) {
boolean valid = true;
for(...; ...; ...) {
...
if(number < 0 || 9 < number) {
valid = false;
break;
}
}
if(valid) {
// show largest input dialog
} else {
// show invalid input dialog
}
// optionally ask the user if they want to exit
// if so, break
}

Why its gets error when my input string ends with spaces..?

// Count total no of words in String
class Word
{
static int Wordcount(String k)
{
int count=0;
char ch[]=k.toCharArray();
for(int i=0;i<k.length();i++)
{
if(ch[i]==32 && ch[i+1]!=32)
{
count++;
}
}
return(++count);
}
public static void main(String... s)
{
String k="java is a programming lan";
/* if input string is "java is a prog lan " then its gives//Exception
*/
int b=Wordcount(k);
System.out.println("Your input String has "+b +" words");
}
}
// Exception aati h agr string khtm ho ri h space se
if(ch[i]==32 && ch[i+1]!=32)
If ch[i] is the last character in the string, and the code tries to check ch[i+1], then you are outside the string's range, and you get an error.
If you want your condition to match spaces at the end of the string, then you can use
if (ch[i]==32 && (i+1 == ch.length || ch[i+1]!=32))
If you want your condition to match only if there is a non-space character after, then you can use
if (ch[i]==32 && i+1 < ch.length && ch[i+1]!=32)
You are checking the current index and the next index at the same time with this condition:
if(ch[i]==32 && ch[i+1]!=32)
If you are on the last character and it's a space, then ch[i+1]!=32 will be evaluated, causing the exception.
To resolve this, make sure you're not at the end of the array when checking index i+1.
if(ch[i]==32 && i < k.length() - 1 && ch[i+1]!=32)

Categories