Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I need help with a method that finds a specific file and then prints out a line of text from that file. The line of text is printed if the string typed in the console matches a string from that line of text. For example if I were to call java Find ring report.txt address.txt Homework.java it should print something like:
report.txt: has broken up an internationa ring of DVD bootleggers that
address.txt: Kris Kringle, North Pole
address.txt: Homer Simpson, Springfield
Homework.java: String file name;
The specified word is always the first command line argument.
This is what I have so far:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
* Code for E11.8. Searches all files specified on the command line and prints out all lines
containing a specified word.
* #Michael Goedken
*/
public class Find
{
/**
Searches file for a word, prints out all lines containing that word.
#param wordToFind the word to find
#param filename the filename for the file to search
*/
public static void findAndPrint(String wordToFind, String filename)
{
String input = args[0];
for (int i = 1; i < args.length; i++)
{
System.out.println(" File " + args[i]);
File one = new File(args[i]);
Scanner in = new Scanner(one);
while (in.hasNext())
{
String line = in.nextLine();
if (line.contains(input))
{
System.out.println(line);
}
}
}
}
/**
First argument of the main method should be the word to be searched
For other arguments of the main method, store the file names to be examined
*/
public static void main(String[] args)
{
// call findAndPrint for each text file
}
}
You're trying to access the array args[] which is not in the scope of the function findAndPrint(). You need to pass args[0] as an argument to the function call statement in the main method:
public static void main(String[] args){
findAndPrint(args[0], args[1]); //for report.txt
findAndPrint(args[0], args[2]); //for address.txt
}
args is an argument of the main method. It is a String array that stores the individual command line inputs. In your case, the contents of the array args[] are = {"ring", "reports.txt", "address.txt", "Homework.java"}.
You can modify your findAndPrint() function in this way now:
static void findAndPrint(String wordToFind, String filename){
Scanner fscan = new Scanner(new File(filename));
String str = "";
while((str = fscan.nextLine()) != null){
if(str.contains(wordToFind))
System.out.println(str);
}
}
I've added main arguments. I haven't ran the code, so that's on you to debug and test.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
* Code for E11.8. Searches all files specified on the command line and prints out all lines containing a specified word.
* #Michael Goedken
*/
public class Find {
/** Searches file for a word, prints out all lines containing that word.
#param wordToFind the word to find
#param filename the filename for the file to search
*/
public static void findAndPrint(String wordToFind, String filename) {
System.out.println(" File " + filename);
File one = new File(filename);
Scanner in;
try {
in = new Scanner(one);
while (in.hasNext()) {
String line = in.nextLine();
if (line.contains(wordToFind)) {
System.out.println(line);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
int length = args.length;
if (length > 0 ) {
String wordToFind = args[0];
// now gather file names, bypassing first string
for (int ii = 1; ii < length; ii++) {
findAndPrint(wordToFind, args[ii]);
}
}
}
}
This seems to work as a solution!
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
/**
* Code for E11.8. Searches all files specified on the command line and prints out all lines
containing a specified word.
* #Michael Goedken
*/
public class Find
{
/**
Searches file for a word, prints out all lines containing that word.
#param wordToFind the word to find
#param filename the filename for the file to search
*/
public static void findAndPrint(String wordToFind, String filename) throws FileNotFoundException
{
Scanner in = new Scanner(new FileReader(filename));
String input = wordToFind;
while (in.hasNext())
{
String line = in.nextLine();
if (line.contains(input))
{
System.out.println(line);
}
}
}
/**
First argument of the main method should be the word to be searched
For other arguments of the main method, store the file names to be examined
*/
public static void main(String[] args) throws FileNotFoundException
{
// call findAndPrint for each text file
findAndPrint("tt", "/Users/MichaelGoedken/Desktop/mary.txt");
findAndPrint("0", "/Users/MichaelGoedken/Desktop/transactions.txt");
}
}
Ok, I think I get your issue now.
You can call your method from the main:
public static void main(String[] args) {
//may need to throw file not found exception here
findAndPrint();
}
Then you need to remove the arguments from your method:
public static void findAndPrint() throws FileNotFoundException {
Scanner in = new Scanner(new FileReader("C:\\yourfilepath\\actualfile.txt"));
//you can get user input etc here if necessary
String input = "pass";
while (in.hasNext()) {
String line = in.nextLine();
if (line.contains(input)) {
System.out.println(line);
}
}
}
Related
I have to do a program and unfortunately I have no idea where to start. It's like we were doing very basic coding and then my teacher went on maternity leave and our substitute thinks we are further along then we actually are. I know how to ready from a file, but I do not know how to put the line into a stack from there.
These are the instructions
1) Read a line and push into a line-stack until the end of file 2) While line_stack is not empty a. Pop one element out and process the following i. Split elements in this line (i.e. numbers) using StringTokenzier ii. Push all numbers into number-stack iii. While number_stack is not empty 1. Pop a number 2. Print a character using that ascii number
If I understand the problem correctly you need to:
Represent a line as a java.lang.String.
Then using java.util.Stack create a Stack< String> and put all the lines there.
Use java.util.StringTokenizer to split each line into multiple parts. Each part will be a String itself.
Turn each part of the line into a number using Integer.valueOf(String)
Put all the numbers into a Stack< Integer>.
Print the right character for each number by casting integer value to char.
I think this may be the solution for your problem:
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Stack;
import java.util.StringTokenizer;
public class LinesProcessor {
private static Stack<String> readLinesFromFile(String fileName) throws IOException {
Stack<String> lines = new Stack<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))) {
String line = null;
while ((line = br.readLine()) != null) {
lines.push(line);
}
}
return lines;
}
private static void processNumbers(Stack<Integer> stackOfNumbers) {
while (!stackOfNumbers.empty()) {
Integer number = stackOfNumbers.pop();
System.out.print((char) number.intValue());
}
}
private static void processLine(String line) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
Stack<Integer> stackOfNumbers = new Stack<>();
while (tokenizer.hasMoreTokens()) {
Integer number = Integer.valueOf(tokenizer.nextToken());
stackOfNumbers.push(number);
}
processNumbers(stackOfNumbers);
}
private static void processLines(Stack<String> stackOfLines) {
while (!stackOfLines.empty()) {
String currentLine = stackOfLines.pop();
processLine(currentLine);
}
}
public static void main(String[] args) throws IOException {
if (args.length < 1) {
System.out.println("Name of file missing");
System.exit(1);
}
String fileName = args[0];
Stack<String> stackOfLines = readLinesFromFile(fileName);
processLines(stackOfLines);
}
}
This is my text file "demo.txt". I have to read value value and assign variables like rule for Success, object for product...
import java.io.*;
import java.util.*;
public class Read {
public static void main(String[] args) throws Exception {
File file=new File("demo.txt");
Scanner s=new Scanner(file);
while(s.hasNextLine()) {
String rule=s.next();
System.out.println(rule);
}
}
}
Here if just want the rule Success to be printed what to do then:
Success
product
If the price of the product is greater than 100 and quantity less than 2 and category is "grocery" then
print the discount equal to 100
Then display the discount is 100
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
*
* Java program to read file using Scanner class in Java.
* java.util.Scanner is added on Java 5 and offer convenient method to read data
*
* #author
*/
public class ScannerExample {
public static void main(String args[]) throws FileNotFoundException {
//creating File instance to reference text file in Java
File text = new File("C:/temp/test.txt");
//Creating Scanner instnace to read File in Java
Scanner scnr = new Scanner(text);
//Reading each line of file using Scanner class
int lineNumber = 1;
while(scnr.hasNextLine()){
String line = scnr.nextLine();
System.out.println("line " + lineNumber + " :" + line);
lineNumber++;
}
}
}
Read more: http://www.java67.com/2012/11/how-to-read-file-in-java-using-scanner-example.html#ixzz4fWXsFF00
I'm designing a program to split data stored in a text file into two separate files based on the label of that data.
Here is a small version of that data.
0,1,2,normal.
5,5,5,strange.
2,1,3,normal.
I use a class to store each line as a sample. The class parses the line to store the last value as the label. I encapsulated each line as an object, because I intend to add features later.
Here is code for the Sample class
import java.util.Scanner;
public class Sample {
String[]str_vals = new String[3];
String label;
Sample(Scanner line) {
for (int i=0; i<3; i++) {
str_vals[i] = line.next();
}
label = line.next();
}
String getValsForCSV() {
StringBuilder retval = new StringBuilder();
for (int i=0; i<3; i++) {
retval.append(str_vals[i]).append(",");
}
retval.append(label).append(".");
return retval+"";
}
String getLabel() {
return label;
}
}
Below is the code in question. My Separator class.
import java.io.*;
import java.util.Scanner;
public class Separator {
public static final String DATAFILE = "src/etc/test.txt";
public static void main(String[] args) throws FileNotFoundException {
runData();
}
public static void runData() throws FileNotFoundException {
try (Scanner in = new Scanner(new File(DATAFILE))) {
// kddcup file uses '.\n' at end of each line
// setting this as delimiter which will consume the period
in.useDelimiter("[.]\r\n|[.]\n|\n");
Sample curr;
while(in.hasNext()) {
// line will hold all fields for a single sample
Scanner line = new Scanner(in.next());
line.useDelimiter(", *");
curr = new Sample(line);
try (
PrintWriter positive = new PrintWriter(new File(DATAFILE+"-pos"));
PrintWriter negative = new PrintWriter(new File(DATAFILE+"-neg"));
) {
if (curr.getLabel().equals("normal")) {
positive.println("GOOD");
} else {
negative.println("BAD");
}
}
}
}
}
}
This issue that I am experiencing is that the code only saves the last Sample seen to its respective file. So with above data the test.txt-neg will be empty and test.txt-pos will have a single line GOOD; it does not have two GOOD's as expected.
If I modify the test.txt data to include only the first two lines, then the files states are reversed (i.e. test.txt-neg has BAD and test.txt-pos is empty). Could someone please explain to me what is going on, and how to fix this error?
Because the error was pointed out in a comment. I wanted to give credit to KevinO and Elliott Frisch for the solution.
As mentioned, I'm creating a new PrintWriter each time and creating the PrintWriter in it's default mode of overwriting a file. As a result it always saves both files based on a single sample.
To correct this error, I have pulled out the instantiations of the PrintWriter to be in the try-with-resource block of the Scanner object
import java.io.*;
import java.util.Scanner;
public class Separator {
public static final String DATAFILE = "src/etc/test.txt";
public static void main(String[] args) throws FileNotFoundException {
runData();
}
public static void runData() throws FileNotFoundException {
try (
Scanner in = new Scanner(new File(DATAFILE));
PrintWriter positive = new PrintWriter(new File(DATAFILE+"-pos"));
PrintWriter negative = new PrintWriter(new File(DATAFILE+"-neg"));
) {
// kddcup file uses '.\n' at end of each line
// setting this as delimiter which will consume the period
in.useDelimiter("[.]\r\n|[.]\n|\n");
Sample curr;
while(in.hasNext()) {
// line will hold all fields for a single sample
Scanner line = new Scanner(in.next());
line.useDelimiter(", *");
curr = new Sample(line);
if (curr.getLabel().equals("normal")) {
positive.println("GOOD");
} else {
negative.println("BAD");
}
}
}
}
}
I am trying to run the below file TemplateMaker.java in Netbeans IDE 8.0.2 and am running into the following error message. Netbeans shows no red indicators for me to fix. Please help.
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:907)
at java.util.Scanner.next(Scanner.java:1416)
at templatemaker.TemplateMaker.processLine(TemplateMaker.java:48)
at templatemaker.TemplateMaker.processLineByLine(TemplateMaker.java:35)
at templatemaker.TemplateMaker.main(TemplateMaker.java:17)
Java Result: 1
Here is my source code:
package templatemaker;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
public class TemplateMaker {
public static void main(String [] args)
throws IOException {
TemplateMaker parser = new TemplateMaker("Book1.txt");
parser.processLineByLine();
log("Done.");
}
/**
Constructor.
#param aFileName full name of an existing, readable file.
*/
public TemplateMaker(String aFileName){
fFilePath = Paths.get(aFileName);
}
/** Template method that calls {#link #processLine(String)}.
* #throws java.io.IOException */
public final void processLineByLine() throws IOException {
try (Scanner scanner = new Scanner(fFilePath, ENCODING.name())){
while (scanner.hasNextLine()){
processLine(scanner.nextLine());
}
}
}
protected void processLine(String aLine){
//use a second Scanner to parse the content of each line
Scanner scanner = new Scanner(aLine);
scanner.useDelimiter("=");
if (scanner.hasNext()){
//assumes the line has a certain structure
String name = scanner.next();
String value = scanner.next();
log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim()));
}
else {
log("Empty or invalid line. Unable to process.");
}
}
// PRIVATE
private final Path fFilePath;
private final static Charset ENCODING = StandardCharsets.UTF_8;
private static void log(Object aObject){
System.out.println(String.valueOf(aObject));
}
private String quote(String aText){
String QUOTE = "'";
return QUOTE + aText + QUOTE;
}
}
Your processLine() is expecting a "name=value" pair. And as MightyPork said you are checking hasNext() once, and then read twice. So if that line does not have an = symbol this will break as scanner wont get the next() token. You should add two hasNext() checks. Ideally you dont need a scanner here. Since you are always expecting two tokens delimited by = you can simply rely on java.util.StringTokenizer as
protected void processLine(String aLine){
StringTokenizer st = new StringTokenizer(aLine, "=");
if(st.countTokens() == 2) {
log("Name is : " + quote(st.nextToken().trim()) + ", and Value is : " + quote(st.nextToken().trim()));
} else {
log("Empty or invalid line. Unable to process.");
}
}
As the stacktrace indicates, the exception was thrown when scanner.next() was called
at java.util.Scanner.next(Scanner.java:1416)
if (scanner.hasNext()){
//assumes the line has a certain structure
String name = scanner.next(); // checked by hasNext()
String value = scanner.next(); // not checked by hasNext()
log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim()));
}
The error must be in the second .next(). You check if the scanner has a next token, but you call .next() twice. So I assume there is 1 token left and you read twice. Also from the API the next() method:
Throws:
NoSuchElementException - if no more tokens are available
IllegalStateException - if this scanner is closed
You can check that easily by adding a System.out.println statement and check what's the last one before the exception (after the first or second call of next())
I just started to code a while back and I'm in the process of dealing with arrays on my own, I understand them in theory but I need some help when it comes to getting practical. I asked my instructor to give me a couple of practices problems and he gave me the following.
using this as your main:
public static void main(String[] args) {
DatosPalabras datos = new DatosPalabras( "words.txt" );
JOptionPane.showMessageDialog(null, datos );
datos.sort();
JOptionPane.showMessageDialog(null, datos);
}
(its in spanish so bear with me) create a class named DatosPalabras and words.txt and make sure your code can:
Read and display words.txt
Display the words in "words.txt" in alphabetical order
I really appreciate the help, I'm a bit stumped but I'm curious to know how I can accomplish this. Thank you!
EDIT:
public class DatosPalabras {
public DatosPalabras(String string) {
// read and display the content of words.txt
}
public void sort() {
// need info on what to use in order to sort words instead of doubles and integers.
}
}
In this example I have 1 file named Q19505617.java. Java only allows you to have 1 public class per file. It is the class that defines the main method. So this example works only because the DatosPalabras class is contained in that file. If you need DatosPalabras to be its own class then put the DatosPalabras in its own file named DatosPalabras.java and change the class signature to be public class DatosPalabras.
import java.io.InputStream;
import java.util.Arrays;
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Q19505617 {
public static void main(String[] args) {
DatosPalabras datos = new DatosPalabras("words.txt");
JOptionPane.showMessageDialog(null, datos);
datos.sort();
JOptionPane.showMessageDialog(null, datos);
}
}
class DatosPalabras {
private String[] lines;
public DatosPalabras(String filename) {
lines = new String[1];
int lineCounter = 0;
InputStream in = Q19505617.class.getResourceAsStream(filename);
Scanner scanner = new Scanner(in);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
if(lineCounter == lines.length) {
lines = Arrays.copyOf(lines, lines.length * 2);
}
lines[lineCounter] = line;
lineCounter++;
}
}
public void sort() {
// put your real sort algorithm here. until then use this:
}
public String toString() {
StringBuilder b = new StringBuilder();
for (String line : lines) {
b.append(line).append("\n");
}
return b.toString();
}
}
You can create a reading Array like this:
String[] Array = new String[number of lines in you txt file];
int i = 0;
// Selecting the txt file
File theFile = new File("bla.txt");
//Creating a scanner to read the file
scan = new Scanner(theFile);
//Reading all the words from the txt file
while (scan.hasNextLine()) {
line = scan.nextLine();
Array[i] = line; // gets all the lines
i++;
Then you create a method for sorting.