While loops aren't repeating - java

This program will read each phone number from the telephones.txt file and will check if it can be translated into one or more words of words.txt file. The output of the program will contain the telephone numbers and their word representatives. (assuming there are words and phones in the file)
public static void main(String[] args) throws IOException
{
Scanner phones = new Scanner(new File("phones.txt"));
Scanner words = new Scanner(new File("words.txt"));
PrintWriter outfile = new PrintWriter(new FileWriter("outfile.txt"));
String number = "", output = "", code = "" ;
//Scans for next phone string
while(phones.hasNext())
{
number = phones.next();
number = number.replace("-","");
//Scans for next word string
while(words.hasNext())
{
code = words.next();
char[] wordChars = null;
wordChars = code.toCharArray();
output = "";
//converts word to digits
for(char wordChar : wordChars)
{
output = output.concat(new String(convert(wordChar)));
}
if(number.equals(output));
{
System.out.println(number + " " + code);
}
break;
}
}
}
This is what I have done so far, except I can't figure out something
if(number.equals(output));
{
System.out.println(number + " " + code);
}
For this line Im trying to see if the output has the same value as the number and if it does have the same value I want to print it out however this is what happens in my program.
I tried tracing my program and this is what i think is happening but its not...
Enter first while loop while theres a phone string continue
Set number to next phone string
Enter 2nd while loop while theres a word string continue
Set code to the CURRENT word string and convert it to a digit value (assume the conversion is correct)
If converted string isn't equal to number I want to continue the loop and search for the next word. And if it is I want to display number + code and continue searching for more words.
After i search through the list of words I want to continue to the next number and repeat the search for words for that number until the first while loop has no more numbers

Answering your second issue:
After i search through the list of words I want to continue to the
next number and repeat the search for words for that number until the
first while loop has no more numbers
Answer:
You should create a new instance if scanner in each iteration, i.e. move the line:
Scanner words = new Scanner(new File("words.txt"));
into the body of the outer loop.
while(phones.hasNext())
{
Scanner words = new Scanner(new File("words.txt"));
number = phones.next();
number = number.replace("-","");
//Scans for next word string
while(words.hasNext())
{
...
}
}

Your inner loop always ends on a break. So the loop body will only ever get executed once. Just put your break into the block that describes the handling of a successful phone number match.

Related

Reading int value from text file, and using value to alter file contents to separate text file.(java)

So I'm trying to read input from a text file, store it into variables, and then output an altered version of that text onto a different file using a variable from the file. I'm using Filereader, Scanner, and Printwriter to do this.
I have to store the last line (which is a number) from this text document and use that number to multiply the body of text onto a different file without including the number.
So the text is:
Original file text
And the output is SUPPOSED to be:
desired output
I'm able to retrieve the number and store it into my multiplier variable and retrieve the text into my string BUT it's stored as a single line if I check inside the console:
how the text is stored seen through console
so it outputs like this on the new file:
undesired output
I'm pretty new to Java, forgive me if there are any questions I can't answer that could help solve any issues with my code.
I've tried adding +"\n" to the file output line but no dice. I've also tried adding it to words += keys.nextLine() +"\n", and it separates the lines in the CONSOLE but not the file itself, unfortunately. Am I at least on the right track?
Here's my code:
public class fileRead {
public static void main(String[] args) throws IOException{
String words = "" ; //Stores the text from file
int multiplier = 1; // Stores the number
FileReader fr = new FileReader("hw3q3.txt");
Scanner keys = new Scanner(fr);
//while loop returns true if there is another line of text will repeat and store lines of text until the last line which is an int
while(keys.hasNextLine())
if (keys.hasNextInt()) { //validation that will read lines until it see's an integer and stores that number
multiplier = keys.nextInt(); //Stores the number from text
} else {
words += keys.nextLine();//Stores the lines of text
keys.nextLine();
}
keys.close();
PrintWriter outputFile = new PrintWriter("hw3q3x3.txt");
for(int i = 1; i <= multiplier; i++) {
outputFile.println(words);
}
outputFile.close();
System.out.println("Data Written");
System.out.println(multiplier);//just to see if it read the number
System.out.println(words); //too see what was stored in 'words'
}
}
See the if-statement below:
words += keys.nextLine(); //Stores the lines of text
if(words.endsWith(words.substring(words.lastIndexOf(" ")+1))) { //detect last word in sentence
words += '\n'; //after last word, append newline
}
...
for(int i = 1; i <= multiplier; i++) {
outputFile.print(words); //change this to print instead of println
}
Basically, after the last word in the sentence within the file we want to append a newline character to start writing the next sentence from new line.
The above if-statement detects the end of the sentence by determining the last word within the words String, and then appending a newline character to the words String. This will yield the result that you are expecting.
Breaking down the expression for you:
words.substring(words.lastIndexOf(" ")+1)
Return the part of the String (substring) that is located at the index of the last whitespace in the String plus 1 (lastIndexOf(" ") + 1) - i.e. we're getting the word after the last whitespace, so the last word.
Entire while-loop:
while(keys.hasNextLine()) {
if (keys.hasNextInt()) { //validation that will read lines until it see's an integer and stores that number
multiplier = keys.nextInt(); //Stores the number from text
} else {
words += keys.nextLine();//Stores the lines of text
if(words.endsWith(words.substring(words.lastIndexOf(" ")+1))) {
words += '\n';
}
}
}

How to pull int value from text file of strings and ints?

I'm trying to write a program that is practically a stack. Given a text file with certain keywords, I want my program to evaluate the text line by line and perform the requested action to the stack.
For example, if the input file is:
push 10
push 20
push 30
The resulting stack should look like:
30
20
10
However, I don't know how to push these values into the stack without hardcoding an int value after the word push. I made a String variable and assigned it to scanner.nextLine()
From there, I compare the line with strLine: if strLine is equal to push followed by some Number, then that number would be pushed on the stack.
However, it seems that the method nextInt() isn't taking this number from the input stream.
Scanner input = new Scanner(file)
int number;
String strLine;
while (input.hasNextLine()){
strLine = input.nextLine();
number = input.nextInt();
if(strLine.equals("push " + number)){
stack.push(number);
}
How can I fix this?
Thank you.
Get the input and split it with space " "!
That will give ["push","1"]
convert the first index to int and then push the value to stack!
while (input.hasNextLine()){
String[] strLine = input.nextLine().split(" ");
if(strLine[0].equals("push")){
stack.push(Integer.parseInt(strLine[1]));
}
else if(strLine[0].equals("pop")){
stack.pop();
}
else{
system.out.println("Please enter a valid input!");
}
}
Hope it helps!
input.nextLine reads the whole line, including the number. What you can do instead is to use input.next() to get the "push" and input.nextInt() to get the number. This example is using Scanner with System.in (so it needs "quit" to exit the while loop), but it should also work with a file (in which case you don't need to type "quit" to exit the program, as it will do so automatically when the input file has no more input). The advantage of using parseInt (as some of the other answers have suggested) is that you can catch any errors in integer input using a try/catch block.
import java.util.Scanner;
import java.util.Stack;
import java.util.InputMismatchException;
public class StackScanner {
public static void main(String args[]) {
Stack<Integer> stack = new Stack<Integer>();
Scanner input = new Scanner(System.in);
int number;
String strLine;
while (input.hasNext()){
strLine = input.next();
if(strLine.equals("push")){
try {
number = input.nextInt();
stack.push(number);
} catch ( InputMismatchException e) {
System.out.println("Invalid input. Try again.");
input.nextLine();
continue;
}
} else {
break;
}
}
System.out.println(stack);
}
}
Sample output:
push 5
push 6
push 3
quit
[5, 6, 3]
change this:
number = input.nextInt();
to this:
number = Integer.parseInt(input.nextLine());
nextLine method parses the whole line including any numbers in the line. So, you need to take care of splitting the line and parsing the number in your code.
Something like below will work where I split the line with spaces. Although, there are many such ways possible.
Scanner input = new Scanner(file);
String strLine;
Stack<Integer> stack = new Stack<>();
int number;
while (input.hasNextLine()){
strLine = input.nextLine();
if(strLine.startsWith("push")){
String[] sArr = strLine.split("\\s+");
System.out.println(strLine);
if(sArr.length==2){
number=Integer.parseInt(sArr[1]);
stack.push(number);
System.out.println(number);
}
}
}
If I understand your problem, I would simply tokenize the line by splitting on whitespace.
It looks like your input is relatively structured: you have a keyword of some kind then whitespace then a number. If your data is indeed of this structure, split the line into two tokens. Read the value from the second one. For example:
String tokens[] = strLine.split(" ");
// tokens[0] is the keyword, tokens[1] is the value
if(tokens[0].equals("push")){
// TODO: check here that tokens[1] is an int
stack.push(Integer.parseInt(tokens[1]));
} else if (tokens[0].equals("pop")) { // maybe you also have pop
int p = stack.pop();
} else if ... // maybe you have other operations

Two problems, using charAt for undefined input and looping output

So, I posted this nearly identical code yesterday, asking about how to leave the punctuation at the end of a reversed sentence after using .split. I'm still struggling with it, but I'm also having another issue with the same code: And here is my screen shot http://i.stack.imgur.com/peiEA.png
import java.util.Scanner;
import java.util.StringTokenizer; // for splitting
public class MyTokenTester
{
public static void main(String\[\] args)
{
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String\[\] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
for (int count = words.length -1; count>=0; count--) // reverse the order and assign backward each token
{
backward += words\[count\] + " ";
}
System.out.println(backward); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
sentinel = sentinel.toLowerCase(); // regardless of case
} while (!sentinel.equals("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
} // end class MyTokenTester][1]][1]
As you guys can probably see my from screen shot, when the user is prompted to add another sentence in, the previous sentence is read back again.
My questions are:
How do I use charAt to identify a character at an undefined index (user input with varying lengths)
How do I stop my sentence from reading back after the user decides to continue.
Again, as I said, I'd posted this code yesterday, but the thread died and I had additional issues which weren't mentioned in the original post.
To address part 2, if you want to stop the sentence from reading back previous input, then reset backward to an empty string, because as it stands now, you're constantly adding new words to the variable. So to fix this, add this line of code right before the end of your do-while loop,
backward = "";
To address part 1, if you want to check the last character in a string, then first you have to know what is the last index of this string. Well, a string has indexes from 0 to str.length()-1. So if you want to access the very last character in the user input, simply access the last word in your words array (indexed from 0 to words.length - 1) by doing the following,
words[count].charAt(words[count].length() - 1);
Note that count is simply words.length - 1 so this can be changed to your liking.
1) So you have this array of strings words. Before adding each word to the backward string, you can use something like: words[count].chartAt(words[count].length() - 1). It will return you the charater at the last position of this word. Now you are able to do you checking to know wether it is a letter or any special char.
2) The problem is not that it is reading the previous line again, the problem is that the backward string still has the previous result. As you are using a + operator to set the values of the string, it will keep adding it together with the previous result. You should clean it before processing the other input to have the result that you want.
here is your code:
import java.util.*;
public class main{
public static void main(String[] args){
Scanner enter = new Scanner(System.in);
String sentinel = ""; // condition for do...while
String backward = ""; // empty string
char lastChar = '\0';
do
{
System.out.println("Please enter a sentence: ");
String sentence = enter.nextLine();
String[] words = sentence.split(" "); // array words gets tokens
// System.out.printf("The string is%s",sentence.substring(sentence.length()));
List<String> items = Arrays.asList(words);
Collections.reverse(items);
System.out.println(generateBackWardResult(items)); // print original sentence in reverse order
System.out.println("Hit any key to continue or type 'quit' to stop now: ");
sentinel = enter.nextLine();
// i use quals ignore case, makes the code more readable
} while (!sentinel.equalsIgnoreCase("quit")); // while the sentinel value does not equal quit, continue loop
System.out.println("Programmed by ----");
} // end main
static String generateBackWardResult(List<String> input){
String result="";
for (String word:input){
result =result +" "+word;
}
return result;
}
} // end class MyTokenTester][1]][1]
there are also some thing to mention:
* never invent the wheel again! (for reverting an array there are lots of approaches in java util packages, use them.)
*write clean code, do each functionality, i a separate method. in your case you are doing the reverting and showing the result in a single method.

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.

My output is assuming the whole file is one line

public static void main(String args[]) throws FileNotFoundException
{
String inputFileName = "textfile.txt";
printFileStats(inputFileName);
}
public static void printFileStats(String fileName) throws FileNotFoundException
{
String outputFileName = "outputtextfile.txt";
File inputFile = new File(fileName);
Scanner in = new Scanner(inputFile);
PrintWriter out = new PrintWriter(outputFileName);
int lines = 0;
int words = 0;
int characters = 0;
while(in.hasNextLine())
{
lines++;
while(in.hasNext())
{
in.next();
words++;
}
}
out.println("Lines: " + lines);
out.println("Words: " + words);
out.println("Characters: " + characters);
in.close();
out.close();
}
I have a text file containing five lines
this is
a text
file
full of stuff
and lines
The code creates an output file
Lines: 1
Words: 10
Characters: 0
However, if I remove the capability for reading the number of words in the file, it correctly states the number of lines (5). Why is this happening?
Your inner while loop is gobbling up the whole file. You want to count the number of words in each line, right? Try this instead:
while (in.hasNextLine())
{
lines++;
String line = in.nextLine();
for (String word : line.split("\\s"))
{
words++;
}
}
Note that splitting on spaces is a very naive approach to tokenization (word-splitting) and will only work for simple examples like the one you have here.
Of course, you could also do words += line.split("\\s").length; instead of that inner loop.
in.hasNext() and in.next() treat all whitespace characters as word separators, including newline characters. Your inner loop is eating all the newlines as it's counting all the words.
This reads next Token, not the line :
in.next();
So it just read next and next and next and dont care about line ending. Space or \n is considered as white space usually, so methods like this one does not make any difference between them.
The reason is, that hasNext() does not care about line breaks.
So, you are entering the while(in.hasNextLine()) loop, but then you are consuming the whole file with the while(in.hasNext()) loop, resulting in 1 line and 10 words.
-> Check the token consumed by hasNext() for EOL-Characters, then increase line count.
OR:
Use String line = scanner.nextLine() to obtain exactly ONE line, and then use a second scanner to fetch all tokens of that line: scanner2 = new Scanner(line); while(scanner2.hasNext())

Categories

Resources