I'm trying to remove all the characters in a String in which the user specifies both the String and the character they want removed. I am only allowed to use for and while loops. When I run my program, the word doesn't print at all. I put a print statement of removeAll inside the if statement and saw that it runs infinitely. Need help in figuring out what I'm doing wrong. Here is the code:
else if (command.equalsIgnoreCase("remove all")) {
System.out.println("Enter the character to remove");
removedLetter = keyboard.next().charAt(0);
int i = 0;
while (i < userInput.length()) {
if (userInput.charAt(i) == removedLetter) {
wordHolderOne = userInput.substring(0,i);
wordHolderTwo = userInput.substring(i+1);
removeAll = wordHolderOne + wordHolderTwo;
}
else {
i++;
}
}
System.out.println(removeAll);
}
I also tried printing i inside the if statement. In the test case where the input word was "yummy" and I tried removing the 'm's, I saw that i would get stuck at 2 and infinitely print.
Related
Example output
file1.txt contents
I have to do a project to determine whether user input is a Palindrome (same letters forwards as backwards). I must create a menu and the user selects whether to input through the console or through a file. I had no issue with reading from the console. I am having trouble producing the correct output through reading Files however.
For a file to be a palindrome, the whole file must be able to be read forwards and backwards and be equal. Then the file contents must be printed and labeled as a Palindrome. I am able to determine if a string is a palindrome within the file, but not the whole file itself. I tried to use .hasNextLine() and compare the lines, but the output is not exactly what is desired.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class PalindromeMachine { //begin class
public static void main(String[] args) { //begin main
boolean choice1 = false;
boolean choice2 = false;
boolean choice3 = false;
while (choice3 == false) {
//create a menu
System.out.println("Welcome to the Palindrome Machine!");
for (int i = 0; i < 35; i++) {
System.out.print("-");
}
System.out.printf("\n1. Read one word from the keyboard");
System.out.printf("\n2. Read one or more words from a file");
System.out.printf("\n3. Exit");
System.out.printf("\nEnter your selection: ");
//gather user input
Scanner user = new Scanner(System.in);
try {
int num = user.nextInt();
if (num > 3 || num < 1) {
System.out.println("Invalid menu option");
}
if (num == 1) {
choice1 = true;
}
if (num == 2) {
choice2 = true;
}
if (num == 3) {
choice3 = true;
}
} catch (InputMismatchException e) {
System.out.println("Invalid menu option");
}
//based on user selection, read in the word or read in lines from a file
while (choice1 == true) {
System.out.printf("Enter the word you would like to check: ");
String checkThis = user.next();
int front = 0;
int back = checkThis.length() - 1;
while (front < back) {
if (checkThis.charAt(front) != checkThis.charAt(back)) {
choice1 = false;
System.out.printf("%s: this word is not a palindrome\n\n", checkThis);
}
front++;
back--;
}
if (choice1 == true) {
System.out.printf("%s: this word is a palindrome\n\n", checkThis);
choice1 = false;
}
} //end while for choice 1
//read from file and determine if palindrome
while (choice2 == true) {
System.out.printf("Enter the file you would like to check: ");
String name;
name = user.nextLine();
try {
File pali = new File(name);
Scanner userRead = new Scanner(pali);
while (userRead.hasNextLine()) {
String checkThis = userRead.nextLine();
//palindrome info
int front = 0;
int back = checkThis.length() - 1;
while (front < back) { //palindrome
if (checkThis.charAt(front) != checkThis.charAt(back)) {
choice2 = false;
System.out.printf("\n%s: this file is not a palindrome",
checkThis);
}
front++;
back--;
} //end palindrome
if (choice2 == true && userRead.hasNextLine() != false) {
System.out.printf(checkThis
+ ": this file is a palindrome\n");
choice2 = false;
} else {
System.out.println("");
System.out.printf(checkThis);
}
} //end of while the file has text
} catch (FileNotFoundException e) {
System.out.printf("\nInvalid file");
}
} // end choice 2
//loop until the user exits + catch inputmismatch
} // end while it loop until exit
} //end main
} //end class
If your intent is to read the entire file and then check if the entire contents are a palindrome or not, then lines in general are a bit of a complicated mess.
Is:
Hello, there!
!ereht ,olleH
A palindromic file? Note that it ends in a newline, so if you attempt to compare byte-for-byte, it's not. If the intent is that it is supposed to 'count', then presumably you'd first trim (lop any whitespace off of the front and back of the entire thing) and then compare byte-for-byte?
If the file's encoding involves characters smearing out over bytes (common - UTF_8, the most common encoding, can do that for any character that isn't simple ASCII), byte-for-byte fails immediately, so I guess character-by-character? Java's 'character' is actually part of surrogate pairs, so symbols from the higher unicode planes, such as emoji, will thus immediately cause trouble (as the emoji is two characters, and therefore won't be the same backwards and forwards). Just go with 'eh, whatever, no files will contain emoji'? Or try to compare codepoints instead?
What about commas, capitals, and other symbol characters? Is this:
Hello, there!
Ereht, olleh!
supposed to 'count'? If you look at Just the actually letters and forget about casing, it is. But a char-by-char comparison will obviously fail. Before you say: That's not palindromic, the usual "A man, a plan, a canal, Panama!" requires that you disregard non-letters and disregard casing.
In any case, it all starts with reading the entire file as a string; Scanner is designed to read tokens (tokens are the things in between the separator), and it has some ugly misplaced baggage in the form of the nextLine() method that you probably shouldn't be using. In any case, it can't read the entire file in one go which makes this vastly more complicated than it needs to be, so step 1 is do not use it.
There's the new file API which is great for this:
import java.nio.file.*;
Path p = Paths.get(fileName);
String contents = Files.readString(p);
That will read the entire contents. We can then remove everything that isn't a letter from it:
contents.toLowerCase().replaceAll("[^a-z]", "");
That thing is a 'regular expression' which is a mini language for text manipulation. [^...] is 'match any character that isn't mentioned here', and a-z is naturally, everything from a to z. In other words, that says: Take the input, lowercase everything, then replace all non-letters with blank, thus giving you only the letters. I turns "A man, a plan, a canal, Panama!" into "amanaplanacanalpanama".
It even gets rid of newlines entirely.
Now you can use the principle at work in your code (start from the beginning and end, fetch the characters there, compare them. If not equal - it is not a palindrome. If equal, increment your 'front pointer', decrement your 'back pointer', and keep going with the comparisons until your pointers are identical, then it is a palindrome.
Scanner has only two uses:
Keyboard input. In which case you should never use .nextLine() (nextLine is broken. It does what the javadoc says it does, which not what anyone expects, hence, do not use it for this) - and always call .useDelimiter("\\R") immediately after making the scanner. This configures it the way you'd expect. Use .nextX() calls to fetch info. next() for strings .nextInt() for integers, etc. All next calls will read entire lines.
Tokenizing inputs. This is only useful if the input is defined in terms of tokens separated by separators. Only a few formats follow that kinda rule. Even your usual 'CSV' files don't, not really - you need custom CSV parsers for that.
"Read an entire file to see if it is palindromic" fits neither use.
I'm having an issue with using the substring method to find a specific character in a string variable. Currently I have a for loop setup to loop over the length of a string variable named name. I then have my substring method inside of my if statement to find my specific character, in this case it is a ".".
I'm not able to get this to work and would appreciate any help. Thank you.
System.out.println("\nEnter name: ");
String name = in.nextLine();
int length = name.length();
for (int x = 0; x < length; x++) {
if(name.substring(x,x+1).equals(".")) {
System.out.println("Error! - name can not contain (.) values\n"
+ "***************************************************");
System.out.println("\nWould you like to capture another name?" +
"\nEnter (1) to continue or any other key to exit");
String opt1 = in.nextLine();
// If statement to run application from the start
if (opt1.equals("1")) {
System.out.println("menu launch");
}
else { System.exit(0); }
}
else { break; }
}
Don't reinvent the wheel. Instead of looping over the characters of the string, you could just use the contains method:
if (name.contains(".")) {
// logic comes here...
While Mureinik is correct on the best way to accomplish your goal, the reason your function does not work is because of your else { break; } statement.
break terminates the loop so unless the very first character is a ., then the loop will exit immediately after the first iteration. When you want to increment the loop, the correct keyword is continue although it is unnecessary in this case because all of the logic is housed inside of the if statement. Since there is no other logic to avoid, you should delete the else statement.
this is my first post so forgive me if i have posted incorrectly. I have a task that i need to complete but i cant get it to work properly. the compiler that i use is bluej. what i need to do is to use scanner to read a text file and compare a user input to the text file. if the input string compares then it should print out that ""The word is on the text file". Unfortunately i cant get this to work. My code reads the file because it prints out to the console but no comparison it s happening. please have a look at my code and give me some pointers. i have been trying to use .equals():
private boolean searchFromRecord(String recordName, String word) throws IOException
{
// Please write your code after this line
File file = new File(recordName);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
for(int i = 0; scanner.hasNextLine(); i++){
String compare = scanner.nextLine();
IO.outputln("word#" + i + ":" + compare);
}
scanner.close();
if (scanner.equals(word)){
return true;
} else{
return false;
}
}
return true;
}
this is what i get output in the console:
Input a word: IRON
AA 888
word#0:BULLET
word#1:1
word#2:AE 1688
word#3:CHEERS
word#4:GAMES
word#5:IRON MAN
word#6:WOLF
word#7:Testing
word#8:Wonderful
The word "IRON" is not in the record.
Here are some problems, along with why they are problems & a suggestion on how they could be fixed:
Problem: closing a scanner within the a loop that uses it will cause an exception. Reason: after we go through the loop once, the scanner will be closed. when we loop through again, an error will occur since the loop uses the scanner, which means the scanner should be "open". Possible solution: move scanner.close() to after the while loop.
Problem: we shouldn't return true at the end of this method. Reason: I'm guessing that this method is supposed to return true if the word is found, and false otherwise. Now, the only way to get to this return statement is if our word doesn't exist in the recordFile; it should return false. Possible solution: return false at the end of the method instead.
Problem: the first line in recordFile will never be checked for equality with word Reason: each method call of scanner.nextLine() will return each line from the recordFile as a String once and only once. In your code, it is called once in the beginning of the while loop's body, but not used to compare with word, then after, it is used in the for loop for comparison Possible solution: remove the line: System.out.println(scanner.nextLine());.
Problem: scanner.equals(word) will probably always return false. Reason: scanner is a Scanner, and word is a String, they should never be equal. Possible solution: replace scanner.equals(word) with compare.equals(word)
Problem: word is not actually compared with each compare. Reason: it is outside the for loop. Possible solution: move the if else block into the end of the for loop's body.
I don't think the while loop is really needed. I strongly recommend that the while loop, is removed, but keep the body.
Problem: Moving the if else block into the for loop, and above the scanner.close() means that the scanner.close() will never be run. Reason: once a return statement is executed, the flow of control immediatly exits the method, and returns to where the method was invoked which makes code after return statements useless. Possible solution: instead of returning right away, declare some sort of boolean variable that will store the return value. have the return value be modified throughout the method, then return the variable at the very end, after scaner.close()
There are many many other ways to fix each of these problems other than the ones suggested here.
I hope you find this helpful! :)
your code, refactored to implement the suggested solutions above:
private boolean searchFromRecord(String recordName, String word) throws IOException {
// Please write your code after this line
Boolean wordFound = false; // indicates if word exists in recordFile.
File file = new File(recordName); // file at path "recordName"
Scanner scanner = new Scanner(file); // reads records from "file"
// iterate through the recordFile, to see if "word" already exists
// within recordFile.
for(int i = 0; scanner.hasNextLine(); i++) {
// read the record from the file
String compare = scanner.nextLine();
IO.outputln("word#" + i + ":" + compare);
// compare the record with our word
if (compare.equals(word)){
wordFound = true;
break; // bail out of loop, our work here is done
}
}
// clean up, and return...
scanner.close();
return wordFound;
}
First, scanner is not a String and it will not equal a String. Second, you are dropping lines - scanner.nextLine() gets the next line, and you print it (but don't save it or compare it). I think you wanted something more like this,
// eats and tosses input.
// System.out.println(scanner.nextLine());
String line = scanner.nextLine();
for(int i = 0; scanner.hasNextLine(); i++){
String compare = scanner.nextLine();
IO.outputln("word#" + i + ": " + compare + " to line: " + line);
if (line.contains(compare)){ // "IRON MAN" starts with "IRON", it doesn't equal IRON.
return true;
}
}
scanner.close();
return false; // <-- default.
Another flavor is to read the whole file into a String variable and look for specified String inside the String.
Code:
File file = new File("C:\\Users\\KICK\\Documents\\NetBeansProjects"
+ "\\SearchWordinFile\\src\\searchwordinfile\\words.txt");
String s="";
try(Scanner input = new Scanner(file)){
input.useDelimiter("\\A");
if (input.hasNext()) {
s = input.next();
}
}catch(Exception e){
System.out.println(e);
}
if(s.contains("IRON"))
System.out.println("I found IRON");
}
Output:
I found IRON
My File content
BULLET
1
AE 1688
CHEERS
GAMES
IRON MAN
WOLF
Testing
Wonderful
This question already exists:
Closed 10 years ago.
Possible Duplicate:
Scanner issue when using nextLine after nextInt
I am creating a client program that needs to read both a String and an integer from my server. Depending on what integer it receives it adds some labels to the GUI. So far, my program reads the integer but skips the String. The following output is the output of my program when I try to write the integers to the program:
Server writes: 1
Server writes: 1
System prints: 1
System prints: j1
System prints: Name
The problem is that I am unable to write a String because it skips the String. How can I avoid this problem (note that I have also tried a for loop)
My code is as following:
int times = client.reciveCommando();
int o = 0;
System.out.println(times);
while (o != times) {
int j = client.reciveCommando();
System.out.println("j"+ j);
String name = client.reciveString();
System.out.println("Name " +name);
createUser(j, name);
o++;
}
The createUser method:
private void createUser(int j, String reciveChat) {
if (j == 1) {
chatPerson1.setVisible(true);
lbl_Chatperson1_userName.setVisible(true);
lbl_Chatperson1_userName.setText(reciveChat);
} else if (j == 2) {
lbl_chatPerson2.setVisible(true);
lbl_userName2.setVisible(true);
lbl_userName2.setText(reciveChat);
} else {
chatPerson3.setVisible(true);
lbl_userName3.setVisible(true);
lbl_userName3.setText(reciveChat);
}
}
The client.reciveCommando method:
public int reciveCommando() throws IOException{
Integer i = input.nextInt();
return i;
}
The client.reciveString method:
public String reciveString(){
String x = input.nextLine();
return x;
}
Hope someone is able to help me with this :)
Thank you in advance.
I don't see anywhere in the loop code where you are incrementing o or changing the value of times. So either the loop is being skipped altogether (ie: times = 0) or some other place in the code is modifying either the loop variable (o) or the loop condition (times) - very bad coding in either case.
Your loop variable/increment rules should be very clear in reading the loop and easily discernible what the start/stop conditions are without needing to read other methods/etc which may modify the values during loop iteration.
My immediate guess is that times = 0, or you would be in an endless loop.
i found the solution to my question it turned out to be quite simple!
first of all let me explain what i ment.
When i my program ran the while loop it basicly skipped the line where it should have recived an input from the server. i found that the reason it did that was that the input.nextLine(); was empty which makes sence when you read the api for input.nextLine();
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.
Returns:
the line that was skipped
since the line that i tried to get was an empty line it would skip and set name to " ".
here is the full complete code for my program and it currently works:
The while loop:
while (o != times) {
int j = client.reciveCommando();
System.out.println("j"+ j);
String name = client.reciveString();
System.out.println("Name " +name);
createUser(j, name);
o++;
}
The client.reciveString();
public String reciveString(){
String x = input.next();
return x;
}
The createUser();
private void createUser(int j, String reciveChat) {
if (j == 1) {
chatPerson1.setVisible(true);
lbl_Chatperson1_userName.setVisible(true);
lbl_Chatperson1_userName.setText(reciveChat);
}else if (j == 2) {
lbl_chatPerson2.setVisible(true);
lbl_userName2.setVisible(true);
lbl_userName2.setText(reciveChat);
}else if (j == 3){
chatPerson3.setVisible(true);
lbl_userName3.setVisible(true);
lbl_userName3.setText(reciveChat);}
Thank you for all of your responses and i will be sure to vote you up :)
I am writing a method to search through a dicitionary to find multiple words of the same length that contain the same letter at a set point. I.e. All words of length 5 that have b as their second letter.
I'm writing this method by TDD is eclipse and so far my method is as follows:
private OpenQueue openQueue = new OpenQueue();
private boolean value;
private int lengthOfWord, numberFound;
private File inFile = new File("src/src/WordList"); //This is a text file
public Search(int length) {
this.lengthOfWord = length;
}
public boolean examine2(int crossingPoint, char letter) {
try {
Scanner input = new Scanner(inFile);
while (input.hasNextLine()) { //while there are words left to be read
String word = input.nextLine();
if(word.length() == lengthOfWord) { //if the word is of the right length
while(word.charAt(crossingPoint-1) == letter){
numberFound = numberFound + 1; //number of solutions is increased by one
openQueue.add(word);//word is added to the open queue
value = true; //value is true when at least one solution has been found
}
}
}
} catch (FileNotFoundException e) {
System.out.println("They File was not Found");
e.printStackTrace();
}
System.out.println(numberFound); //returns number of words found
return value; //should return true if there is at least one word
}
For my test I trying to find all five letter words that have a second letter b and there are several words that fit this as I've checked manually. However when I run JUnit it says that it expected true but it was false.
The code runs up to but not past the while(word.charAt(crossingPoint-1) == letter) loop, as previously I added in System.out.println("Here") before this loop to check were the code runs until.
I'm not sure how to fix this in order for the code to run without the test failing. Thanks for your help.
It's hard to look at this code -- arghh! But there appear to be at least one syntax error. I'm not sure whether you just copied it into this question incorrectly, otherwise I don't even see how it can compile. You put parentheses after lengthOfWord which makes it look like a no-argument method or method call, but you appear to want to use it as an integer variable.
Also inFile and numberFound do not appear to be defined. You will have to provide more context.