Java not detecting file contents - java

I'm having difficulty figuring out why this isn't working. Java simply isn't executing the while loop, file apparently does not have a next line.
fileName = getFileName(keyboard);
file = new Scanner (new File (fileName));
pass = true;
String currentLine;
while (file.hasNextLine()) {
currentLine = file.nextLine();
System.out.println(reverse(currentLine));
}
Here is the file I am testing this with. I got it to work with the first few paragraphs but it seems to simply stop working...:
Jabberwocky
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
"Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jubjub bird, and shun
The frumious Bandersnatch!"
He took his vorpal sword in hand:
Long time the manxome foe he soughtó
So rested he by the Tumtum tree,
And stood awhile in thought.
And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wood,
And burbled as it came!
One, two! One, two! and through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.
"And hast thou slain the Jabberwock?
Come to my arms, my beamish boy!
O frabjous day! Callooh! Callay!"
He chortled in his joy.
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
——from Through the Looking-Glass, and What Alice Found There (1872).
/*
* Lab13a.java
*
* A program that prompts the user for an input file name and, if that file exists,
* displays each line of that file in reverse order.
* Used to practice simple File I/O and breaking code up into methods as well as a first
* step to implementing Lab13b.java - reversing the entire file and Lab13c.java writing
* output to a separate output file.
*
* #author Benjamin Meyer
*
*/
package osu.cse1223;
import java.io.*;
import java.util.*;
public class Lab13a {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String fileName = "";
Scanner file;
boolean pass = false;
while (!pass) {
try {
fileName = getFileName(keyboard);
file = new Scanner (new File (fileName));
pass = true;
String currentLine;
while (file.hasNextLine()) {
currentLine = file.nextLine();
System.out.println(reverse(currentLine));
}
}
catch (FileNotFoundException e) {
System.out.println("There was a problem reading from " + fileName);
System.out.println("Goodbye.");
return;
}
}
}
// Given a Scanner as input prompts the user to enter a file name. If given an
// empty line, respond with an error message until the user enters a non-empty line.
// Return the string to the calling program. Note that this method should NOT try
// to determine whether the file name is an actual file - it should just get a
// valid string from the user.
private static String getFileName(Scanner inScanner) {
boolean pass = true;
String fileName = "";
while (pass) {
System.out.print("Enter an input name: ");
fileName = inScanner.nextLine();
if (fileName.length()!=0) {
pass = false;
}
else {
System.out.println("You cannot enter an empty string.");
}
}
return fileName;
}
// Given a String as input return the reverse of that String to the calling program.
private static String reverse(String inString) {
if (inString.length()==0) {
return "";
}
String reversed = "" + inString.charAt(inString.length()-1);
for (int x = inString.length()-2; x>=0; x--) {
reversed = reversed + inString.charAt(x);
}
return reversed;
}
}

The issue might lie in your implementation of your functions getFilename() or reverse(). Since you have stated that you got it to work with a few of the paragraphs I doubt that your program is failing due to your file handling. It might be in the logic you are using to reverse the strings in the file that is causing the issue.

Related

How to compare an user input to a text file using BufferedReader

So I'm working on a project that requires me to compare a users input to a list of words in a txt file. I've been trying to compare the the input as a string to the BufferReader, but it hasn't been working. Any suggestions is welcomed
Here's the code for the project
public class Lab5Program1 {
public static void main(String[] args) throws IOException {
File file = new File("fileName");
BufferedReader br = new BufferedReader(new FileReader(file));
/** In order to read a text file that is inside the package, you need to call the actual file and then pass it
* to the BufferedReader. So that it can be used in the file**/
// String[] wordArray = { "hello", "goodbye", "cat", "dog", "red", "green", "sun", "moon" };
String isOrIsNot, inputWord;
// This line asks the user for input by popping out a single window
// with text input
inputWord = JOptionPane.showInputDialog(null, "Enter a word in all lower case:");
// if the inputWord is contained within wordArray return true
if (wordIsThere(inputWord, br))
isOrIsNot = "is"; // set to is if the word is on the list
else
isOrIsNot = "is not"; // set to is not if the word is not on the list
// Output to a JOptionPane window whether the word is on the list or not
JOptionPane.showMessageDialog(null, "The word " + inputWord + " " + isOrIsNot + " on the list.");
} //main
public static boolean wordIsThere(String findMe, BufferedReader bufferedReader) throws IOException {
// for (int i = 0; i < bufferedReader.lines() ; i++){
// if (findMe.equals(theList[i])){
// return true;
// }
// }
while((findMe = bufferedReader.readLine()) != null) {
if (findMe.equals(bufferedReader.readLine())){
return true;
}
}
return false;
} // wordIsThere
}
The error is coming from the function to check if the word exists. Each line being reader from the text file is not being checked with findMe. Made these changes, it works.
public static boolean wordIsThere(String findMe, BufferedReader br) throws IOException {
for (String word = br.readLine() ; word != null; word = br.readLine()) {
if (word.equals(findMe))
return true;
}
return false;
}
In method wordIsThere, parameter findMe is the word you are looking for. However you overwrite the value of the parameter with the line read from the file.
You should declare a separate variable to store the line of text that you read from the file.
public static boolean wordIsThere(String findMe, BufferedReader bufferedReader) throws IOException {
String line = bufferedReader.readLine(); // read first line of file
while(line != null) {
if (findMe.equals(line)){
return true;
}
line = bufferedReader.readLine(); // read next line of file
}
return false;
}
Also note that since you are using JOptionPane to get user input, a separate thread is launched and this thread does not terminate when method main terminates. Hence you should call method exit, of class java.lang.System in the last line of main, in class Lab5Program1. Otherwise, each time you run class Lab5Program1 you will start a new JVM that will not terminate.
For console applications, you can use class java.util.Scanner to get user input.
Scanner stdin = new Scanner(System.in);
System.out.print("Enter a word in all lower case: ");
String inputWord = stdin.nextLine();
Also consider closing files when you have finished with them. In your case it is not necessary since the file is automatically closed when the JVM terminates.

How to use "write" to get the information in a for each loop

Im currently working on a project at school, where I am to switch out a certain word in an ArrayList. The word is written several times in the list. Im going to change it with a random word from a different ArrayList. My loop currently works as I wanted to, surly I can make it better, but it works atm. The word im changing is "ADJEKTIV"
My problem is that I cant get it to write to a file. It will print out using the System.out.println to terminal, but the assignment tell us to write it to the file.
public class StoryCreator
{
private InputReader reader;
private OutputWriter writer;
private Random random;
public StoryCreator()
{
reader = new InputReader();
writer = new OutputWriter();
random = new Random();
}
public void createAdjectiveStory(String storyFilename, String adjectivesFilename, String outputFilename)
{
ArrayList<String> storyWords = reader.getWordsInFileWithScanner(storyFilename);
ArrayList<String> adjectives = reader.getWordsInFileWithScanner(adjectivesFilename);
String replaceKeyword = "ADJEKTIV";
for(String words : storyWords)
{
if(storyWords.contains("ADJEKTIV"))
{
int adjectiveNumber = random.nextInt(adjectives.size());
String randAdjective = adjectives.get(adjectiveNumber);
String story = words.replace(replaceKeyword,randAdjective);
System.out.println(story);
writer.write(storyWords, outputFilename);
}
}
}
I've gotten the text to be written in a file, but it doesn't write the file where I have replaced the words I want. It writes the file before the words are changed.
The output writer class
public class OutputWriter
{
/**
* Constructor for objects of class OutputWriter
*/
public OutputWriter()
{
}
/**
* Writes a list of words to a file. The words are separated by the 'space' character.
*
* #param output the list of words
* #param filename the name of the output file
*/
public void write(ArrayList<String> output, String filename)
{
try {
FileWriter out = new FileWriter(filename);
for(String word : output) {
out.write(word + " ");
}
out.close();
}
catch(IOException exc) {
System.out.println("Error writing output file: " + exc);
}
}
}
Hope someone knows how I can manage this.
You are looping through String word : storyWords and replacing the word object with the random word. So, far so good.
The problem I think you have is here:
String story = words.replace(replaceKeyword,randAdjective);
System.out.println(story);
writer.write(storyWords, outputFilename);
You write out the story object using System.out.println(story) but then you write out the storyWords object to the file. This storyWords list will include the old String as you haven't replaced it with story (Which has the replacement in). This is why you are seeing the old word when writing to a file.
This brings up a new issue of the replacement of the String in storyWords as trying to modify within a for-each loop will throw an exception.
I think it would be better to use a normal for loop instead of a for-each to keep the position of the String inside storyWords so you can make the replace.
for(int i = 0 ; i < storyWords.size() ; i++)
{
String word = storyWords.get(i);
if(word.contains("ADJEKTIV"))
{
int adjectiveNumber = random.nextInt(adjectives.size());
String randAdjective = adjectives.get(adjectiveNumber);
String story = word.replace(replaceKeyword, randAdjective);
System.out.println(story);
storyWords.set(i, story);
writer.write(storyWords, outputFilename);
}
}
I think that should be the kind of thing you are looking for.
I have kept the code as close as possible to what you had originally written.
I did change the storyWords.contains("ADJEKTIV") to word.contains("ADJEKTIV") making the assumption that is what you meant.

Java - Searching through a file without using a list

I'm trying to create a program that will let a user search through a file for a specific word, without creating an array and adding all the contents of the file to it (so it could be easily ported and used with different file sizes etc). Below is my code:
package test2;
import java.io.InputStream;
import java.util.Scanner;
import javax.swing.JOptionPane;
/**
*
* #author Kafaka157
*/
public class Prep2 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
InputStream stream = Prep1.class.getResourceAsStream("words.txt");
Scanner scanner = new Scanner(stream);
while(scanner.hasNextLine()){
String word = JOptionPane.showInputDialog("Input word to look for: ");
if(word.equals(scanner.next().trim())){
JOptionPane.showMessageDialog(null, word + " found"); // found
break;
}else{
JOptionPane.showMessageDialog(null,word + " not found"); // not found
break;
}
}
}
}
The above is my code, I get no build errors or anything, however it won't return found on words which I know are in the file. It seems to default to else at every instance, any help / idea where I'm going wrong? Many thanks.
public static void main(String[] args) {
InputStream stream = Prep1.class.getResourceAsStream("words.txt");
Scanner scanner = new Scanner(stream);
boolean wordFound = false;//initially set it to false
String word = JOptionPane.showInputDialog("Input word to look for: ");
while(scanner.hasNextLine()){
if(word.equals(scanner.next().trim())){
//after the loop would be a better place to show below notification
//JOptionPane.showMessageDialog(null, word + " found"); // found
wordFound = true;//make the flag as true and break out of the loop
break;
}/*else{
JOptionPane.showMessageDialog(null,word + " not found"); // not found
break;
}*/
}
if(wordFound)
JOptionPane.showMessageDialog(null, word + " found"); // found
else
JOptionPane.showMessageDialog(null,word + " not found");
Few modifications needed and that should do. The comments provided above should serve the purpose. The main problem is that you are breaking out of the loop after checking the first word itself!

Parse a file to match certain pattern and return subsequent lines having different pattern

I have a log file and I am trying to parse the file in following way:
The file to be parsed looks like:
filename.......f1
This test is associated with file 1 - ignore it
filename.......f2
This test is associated with file 2 -ignore it
filename.......f3
This test is associated with file 3 - line 1 - do not ignore it
This test is associated with file 3 - line 2 - do not ignore it
filename.......f4
This test is associated with file 4 - ignore it
filename.......f5
This test is associated with file 5 - do not ignore it
Let's suppose we are macthing the text in file using Regx pattern as follows:
MATCHING_PATTERN1 - for "filename.......f[X]"
MATCHING_PATTERN2 - for "This test is associated with file [X] - do not ignore it"
I'm using following code:
package org.c2pfiscbk.tutorial;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestLogParser {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
LogParser lp = new LogParser();
lp.logReader();
}
}
class LogParser {
public void logReader(){
File input = new File("file_location/fileName.log");
try {
Scanner scanner = new Scanner(input);
while(scanner.hasNext()){
String dLine = scanner.nextLine();
if (dLine.matches("MATCHING_PATTERN1")){
System.out.println(dLine);
}
else{
if (dLine.matches("MATCHING_PATTERN2")){
System.out.println(dLine);
}
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
My output using above code is:
filename.......f1
filename.......f2
filename.......f3
This test is associated with file 3 - line 1 - do not ignore it
This test is associated with file 3 - line 2 - do not ignore it
filename.......f4
filename.......f5
This test is associated with file 5 - do not ignore it
Whereas, my requirment is:
filename.......f3
This test is associated with file 3 - line 1 - do not ignore it
This test is associated with file 3 - line 2 - do not ignore it
filename.......f5
This test is associated with file 5 - do not ignore it
Which means I am intrested only in the filenames (with MATCHING_PATTERN1) followed by certain text (with MATCHING_PATTERN2) along with the text (with MATCHING_PATTERN2) itself.
I don't want to use sed or egrep or any other external tool.
You need to create a boolean variable to say whether you need to print the first match (since you only want to print it once for all the associated pattern 2's). Then as the answers above suggest, you can then use a cache style variable to print the file name once.
String fileName=null;
boolean printFilename = false;
while(scanner.hasNext()){
String dLine = scanner.nextLine();
if (dLine.matches("MATCHING_PATTERN1")){
fileName = dLine;
printFilename = true;
}
else{
if (dLine.matches("MATCHING_PATTERN2")){
if (printFilename) {
System.out.println(fileName);
printFilename = false;
}
System.out.println(dLine);
}
}
}
Simply store the filename in some variable and print it only when you are in the
String fileName=null;
while(scanner.hasNext()){
String dLine = scanner.nextLine();
if (dLine.matches("MATCHING_PATTERN1")){
fileName = dname;
}
else{
if (dLine.matches("MATCHING_PATTERN2")){
System.out.println(fileName );
System.out.println(dLine);
}
}
}
Keep track of all the lines to print back, and eventually print them:
String currentHeader = scanner.nextLine();
List<String> followingLines = new ArrayList<>();
while(scanner.hasNext()){
String line = scanner.nextLine();
if (line.matches("MATCHING_PATTERN1")){
// new header, let's print the lines if there are lines to print
if(!followingLines.isEmpty()) {
System.out.println(currentHeader);
for(String followingLine : followingLines) {
System.out.println(followingLine);
}
}
// reset
currentHeader = line;
followingLines.clear();
} else if (line.matches("MATCHING_PATTERN2")){
followingLines.add(line);
}
}
// print last one
if(!followingLines.isEmpty()) {
System.out.println(currentHeader);
for(String followingLine : followingLines) {
System.out.println(followingLine);
}
}
You will have run a second loop to get your result
while(scanner.hasNext()){
String dLine = scanner.nextLine();
if (dLine.matches("MATCHING_PATTERN1")){
System.out.println(dLine);
String dLine2 = scanner.nextLine();
while(scanner.hasNext() && dLine2.matches("MATCHING_PATTERN2"){
System.out.println(dLine2);
}
}
}
Well your output is logical, since the first match makes it print any "filename.... f[X]", including the ones you don't want. Make the first match store the line in a variable instead or printing it, print that variable in the second match if it's not printed yet and it'll work as you want:
String cacheLine = "";
String lastPrintedCacheLine = "";
while(scanner.hasNext()){
String dLine = scanner.nextLine();
if (dLine.matches("MATCHING_PATTERN1")){
cacheLine = dLine;
} else if (dLine.matches("MATCHING_PATTERN2")){
if (! cacheLine.equals(lastPrintedCacheLine)) {
System.out.println(cacheLine);
lastPrintedCacheLine = cacheLine;
}
System.out.println(dLine);
}
}
Verified. However, the answer from Riggy works as well and costs less.
Note that your use of the {} block after the else is obsolete and you could simply use else if. Makes the code a little less messy imho.

Preserving line breaks and spacing in file IO

I am workig on a pretty neat problem challenge that involves reading words from a .txt file. The program must allow for ANY .txt file to be read, ergo the program cannot predict what words it will be dealing with.
Then, it takes the words and makes them their "Pig Latin" counterpart, and writes them into a new file. There are a lot more requirements to this problem but siffice to say, I have every part solved save one...when printng to the new file I am unable to perserve the line spacing. That is to say, if line 1 has 5 words and then there is a break and line 2 has 3 words and a break...the same must be true for the new file. As it stands now, it all works but all the converted words are all listed one after the other.
I am interested in learning this so I am OK if you all wish to play coy in your answers. Although I have been at this for 9 hours so "semi-coy" will be appreaciated as well :) Please pay close attention to the "while" statements in the code that is where the file IO action is happening. I am wondering if I need to utilize the nextLine() commands from the scanner and then make a string off that...then make substrings off the nextLine() string to convert the words one at a time. The substrings could be splits or tokens, or something else - I am unclear on this part and token attempts are giving me compiler arrors exceptions "java.util.NoSuchElementException" - I do not seem to understand the correct call for a split command. I tried something like String a = scan.nextLine() where "scan" is my scanner var. Then tried String b = a.split() no go. Anyway here is my code and see if you can figure out what I am missing.
Here is code and thank you very much in advance Java gods....
import java.util.*;
import javax.swing.*;
import java.io.*;
import java.text.*;
public class PigLatinTranslator
{
static final String ay = "ay"; // "ay" is added to the end of every word in pig latin
public static void main(String [] args) throws IOException
{
File nonPiggedFile = new File(...);
String nonPiggedFileName = nonPiggedFile.getName();
Scanner scan = new Scanner(nonPiggedFile);
nonPiggedFileName = ...;
File pigLatinFile = new File(nonPiggedFileName + "-pigLatin.txt"); //references a file that may or may not exist yet
pigLatinFile.createNewFile();
FileWriter newPigLatinFile = new FileWriter(nonPiggedFileName + "-pigLatin.txt", true);
PrintWriter PrintToPLF = new PrintWriter(newPigLatinFile);
while (scan.hasNext())
{
boolean next;
while (next = scan.hasNext())
{
String nonPig = scan.next();
nonPig = nonPig.toLowerCase();
StringBuilder PigLatWord = new StringBuilder(nonPig);
PigLatWord.insert(nonPig.length(), nonPig.charAt(0) );
PigLatWord.insert(nonPig.length() + 1, ay);
PigLatWord.deleteCharAt(0);
String plw = PigLatWord.toString();
if (plw.contains("!") )
{
plw = plw.replace("!", "") + "!";
}
if (plw.contains(".") )
{
plw = plw.replace(".", "") + ".";
}
if (plw.contains("?") )
{
plw = plw.replace("?", "") + "?";
}
PrintToPLF.print(plw + " ");
}
PrintToPLF.close();
}
}
}
Use BufferedReader, not Scanner. http://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html
I leave that part of it as an exercise for the original poster, it's easy once you know the right class to use! (And hopefully you learn something instead of copy-pasting my code).
Then pass the entire line into functions like this: (note this does not correctly handle quotes as it puts all non-apostrophe punctuation at the end of the word). Also it assumes that punctuation is supposed to go at the end of the word.
private static final String vowels = "AEIOUaeiou";
private static final String punct = ".,!?";
public static String pigifyLine(String oneLine) {
StringBuilder pigified = new StringBuilder();
boolean first = true;
for (String word : oneLine.split(" ")) {
if (!first) pigified.append(" ");
pigified.append(pigify(word));
first = false;
}
return pigified.toString();
}
public static String pigify(String oneWord) {
char[] chars = oneWord.toCharArray();
StringBuilder consonants = new StringBuilder();
StringBuilder newWord = new StringBuilder();
StringBuilder punctuation = new StringBuilder();
boolean consDone = false; // set to true when the first consonant group is done
for (int i = 0; i < chars.length; i++) {
// consonant
if (vowels.indexOf(chars[i]) == -1) {
// punctuation
if (punct.indexOf(chars[i]) > -1) {
punctuation.append(chars[i]);
consDone = true;
} else {
if (!consDone) { // we haven't found the consonants
consonants.append(chars[i]);
} else {
newWord.append(chars[i]);
}
}
} else {
consDone = true;
// vowel
newWord.append(chars[i]);
}
}
if (consonants.length() == 0) {
// vowel words are "about" -> "aboutway"
consonants.append("w");
}
consonants.append("ay");
return newWord.append(consonants).append(punctuation).toString();
}
You could try to store the count of words per line in a separate data structure, and use that as a guide for when to move on to the next line when writing the file.
I purposely made this semi-vague for you, but can elaborate on request.

Categories

Resources