Im currently trying to write a program that counts the amounts of times different words are being used in a text, and then attach the values to a hashmap. In the main part of the program i use a scanner to read in the file with the text, and i initiate the GenWordCtr with another scanner thats supposed to read in a file with words i want excluded (words like "this, her, that"). Ive made sure that the string sent to op.process is lowercased, however when i run the program it still adds all the values that i want excluded from the statistics. What am i doing wrong? I know the main program works, ive tried it with single words.
TLDR - i want words excluded using a scanner to read in a text, for some reason they arent being excluded in the "process" operation of my program.
package textproc;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Holgersson {
public static final String[] REGIONS = { "blekinge", "bohuslän", "dalarna", "dalsland", "gotland", "gästrikland",
"halland", "hälsingland", "härjedalen", "jämtland", "lappland", "medelpad", "närke", "skåne", "småland",
"södermanland", "uppland", "värmland", "västerbotten", "västergötland", "västmanland", "ångermanland",
"öland", "östergötland" };
public static void main(String[] args) throws FileNotFoundException {
Scanner s = new Scanner(new File("../lab1/nilsholg.txt"));
Scanner stopwords = new Scanner(new File("undantagsord.txt"));
s.useDelimiter("(\\s|,|\\.|:|;|!|-|\\?|'|\\\")+"); // se handledning
TextProcessor gen = new GeneralWordCounter(stopwords);
while (s.hasNext()) {
String word = s.next().toLowerCase();
gen.process(word);
}
s.close();
gen.report();
}
}
package textproc;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class GeneralWordCounter implements TextProcessor {
private Map<String, Integer> m;
private Scanner excep;
GeneralWordCounter(Scanner r){
Map<String, Integer> m = new HashMap<String, Integer>();
this.m = m;
excep = r;
}
#Override
public void process(String word) {
// TODO Auto-generated method stub
boolean bin = false;
while(excep.hasNext() && bin == false) {
if(word.equals(excep.next().toLowerCase())) {
bin = true;
}
}
if(!bin) {
if(m.containsKey(word)) {
m.put(word, (m.get(word) + 1));
}
else {
m.put(word, 1);
}
}
}
#Override
public void report() {
// TODO Auto-generated method stub
for(String key : m.keySet()) {
if(m.get(key) >= 200) {
System.out.println(key + " - " + m.get(key));
}
}
}
}
You are using same Scanner instance for stopwords inside the loop, which might be getting exhausted within few number of below loops.
TextProcessor gen = new GeneralWordCounter(stopwords);
while (s.hasNext()) {
String word = s.next().toLowerCase();
gen.process(word);
}
Imagine this way, you have started above loop and passed the Scanner instance and when you called process method it started loop for word and reached to end of the file for second Scanner. Now, in the next loop you again called process method but this time pointer will be already at the end of the file as you are using same instance. So, you won't get expected output.
Instead, you need to create new instance of Scanner for each process method call.
public void process(String word) {
Scanner excep = new Scanner(new File("undantagsord.txt"));
// your code.
Related
I'm having trouble properly getting one line of text at a time from a file onto a queue without taking the whole file into the queue. For example, I'd like only Write a program that reads a Java source file as an argument and produces an index of all identifiers in the file. For each identifier, print all lines in which it occurs. For simplicity, we will consider each string consisting only of letters, numbers, and underscores an identifier.
Declare a Scanner in for reading from the source file and call in.useDelimiter("[^A-Za-z0-9_]+") Then each call to next returns an identifier.
public class Main { to get added to the queue but instead the whole file text is put into the queue instead of a line at a time. Sorry if my question is unclear
// Write a program that reads a Java source file as an argument and produces an index of all
// identifiers in the file. For each identifier, print all lines in which it occurs. For simplicity,
// we will consider each string consisting only of letters, numbers, and underscores an identifier.
// Declare a Scanner in for reading from the source file and call in.useDelimiter("[^A-Za-z0-9_]+").
// Then each call to next returns an identifier.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class E_15 {
public static void main(String[] args) throws FileNotFoundException
{
// get scanner input from file
Scanner fileInput = new Scanner(new File ("C:/Users/ramir/IdeaProjects/PA_7/src/Main.java"));
Queue<String> test = new LinkedList<String>();
ArrayList<String> phrase = new ArrayList<String>();
/*
List<String> result = new ArrayList<String>();
Scanner s = new Scanner(is);
s.useDelimiter(delimiter);
*/
// Iterates till end of file
while (fileInput.hasNextLine())
{
// Here is the issue. Data will end up
// containing the whole file instead of only that line
String data = fileInput.nextLine();
Scanner in = new Scanner(data);
in.useDelimiter("[^A-Za-z0-9_]+");
// I believe around here or before is the issue that I'm having.
// It adds all the file instead of only that line
// Also trying to figure out how to display each line that it's displayed on
// What the first one should look like for example
// 0: public occurs in:
// public class Main {
// public static void main(String[] args) {
//System.out.println(data);
test.add(data);
while(in.hasNext())
{
// Getting each phrase/word into ArrayList
String token = in.next();
phrase.add(token);
}
in.close();
}
int index = 0;
// This part works fine
for(String num : phrase)
{
// printing the key
System.out.println(index + ": " + num + " occurs in:");
// printing the values
// This to print out what
for(String line : test)
{
System.out.println(line);
}
System.out.println();
++index;
}
}
}
// Just java class get file front
// This is fine
public class Main {
public static void main(String[] args) {
int a_1 = 100;
System.out.println(a_1);``
}
}
I'd like it to only show System.out.println(a_1) because the line that's it's on See This
. I'm also have trouble printing it in all the lines that occur.
import java.io.*;
import java.util.Scanner;
public class ReadLineByLineExample2
{
public static void main(String args[])
{
try
{
//the file to be opened for reading
FileInputStream fis=new FileInputStream("Demo.txt");
Scanner sc=new Scanner(fis); //file to be scanned
//returns true if there is another line to read
while(sc.hasNextLine())
{
System.out.println(sc.nextLine()); //returns the line that was skipped
}
sc.close(); //closes the scanner
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Try studying the above code. I hope it will help. Otherwise, you might need to open this link for more detail.
I'm attempting to read in a csv file, I've created a test file with 9 entries and their value, but my code won't read past the second line , it says the file isn't found past the second key, I've tried tweeking it as much as possible, can someone help me? sample input would include something like this but in a csv file (so each in a new line, I'm new here and still learning to edit text here):
Diego,2
Maria,2
Armando,5
Ken, 1
public static void main(String[] args) {
HashMap<String, Integer> h = new HashMap<String, Integer>(511);
try
{
Scanner readIn = new Scanner (new File ("test1.csv") );
System.out.println("I'm here 1");
while ( readIn.hasNext() )
{
System.out.print(readIn.next());// for testing purposes only
System.out.println("Check 2"); // for testing purposes only
String line = readIn.nextLine();
String str[] = line.split(",");
for (int i = 0; i < str.length ; i++)
{
String k = str[0];
int v = Integer.parseInt(str[1]);
h.insert(k , v);
}
System.out.println(h.toString());
}
readIn.close();
}
catch (ArrayIndexOutOfBoundsException ob)
{
System.out.println(" - The file wasn't found." );
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
A call to next() or nextLine() should be preceeded with the call to hasNext().But in you code you have checked if hasNext() returns true in the while loop,and then invoked both next() and nextLine() inside the loop.
You can modify your code as below:
while ( readIn.hasNext() )
{
String line = readIn.nextLine();
String str[] = line.split(",");
for (int i = 0; i < str.length ; i++)
{
String k = str[0];
int v = Integer.parseInt(str[1]);
h.put(k , v);
}
System.out.println(h.toString());
}
Your for loop isn't actually serving a purpose. You will notice that you never actually reference i in the loop. Prior to the OP's answer I believe you were trying to split on a string that didn't have a comma, but your code assumes that one will be there and hence the out of bounds exception. This relates to why I was telling you that the println() was problematic.
As far as your question about hasNext(), this is the only way you will know that you can read another line from the file. If you try to read past the end you will run into problems.
Rather writing code to read CSV file on your own. I'd suggest you to use standard libraries like Apache Commons CSV. It provides more methods to deal with CSV, Tab separated file, etc...
import java.io.FileReader;
import java.util.List;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
public class SO35859431 {
public static void main(String[] args) {
String filePath = "D:\\user.csv";
try {
List<CSVRecord> listRecords = CSVFormat.DEFAULT.parse(new FileReader(filePath)).getRecords();
for (CSVRecord csvRecord : listRecords) {
/* Get record using index/position */
System.out.println(csvRecord.get(0));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
First there is no such insert() method in HashMap class.The correct one is put(k, v) & in while loop it should be hasNext(). Follow is my code alternate the BufferedReader.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package read;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Scanner;
/**
*
* #author Isuru Rangana Jr
*/
public class Read {
/**
* #param args the command line arguments
*/
public static void main(String args[]) throws FileNotFoundException, IOException {
HashMap<String, Integer> h = new HashMap<String, Integer>();
try {
BufferedReader readIn = new BufferedReader(new FileReader(new File("test.csv")));
while (readIn.ready()) {
String line = readIn.readLine();
String str[] = line.split(",");
for (int i = 0; i < str.length; i++) {
String k = str[0];
int v = Integer.parseInt(str[1]);
h.put(k, v);
}
System.out.println(h.toString());
}
readIn.close();
} catch (ArrayIndexOutOfBoundsException ob) {
System.out.println(" - The file wasn't found.");
}
}
}
I am trying to search a string in a file in java and this is what, I tried . In the below program I am getting output as No Data Found and I am sure that the file has the word which I am searching
import java.io.*;
import java.util.Scanner;
public class readfile {
static String[] list;
static String sear = "CREATE";
public void search() {
Scanner scannedFile = new Scanner("file.txt");
while (scannedFile.hasNext()) {
String search = scannedFile.next();
System.out.println("SEARCH CONTENT:"+search);
if (search.equalsIgnoreCase(sear)) {
System.out.println("Found: " +search);
}
else {
System.out.println("No data found.");
}
}
}
public static void main (String [] args) throws IOException {
readfile read = new readfile();
read.search();
}
}
Don't do:
search.equalsIgnoreCase(sear)
Try:
search.toUpperCase().contains(sear)
I think the search is the whole String of the File, so you never would become true with equals.
Use nextLine() instead of next() and then use split. Like this :
What's the difference between next() and nextLine() methods from Scanner class?
Difference :
next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
Use following code :
String search = scannedFile.nextLine();
String[] pieces = data.split("\\s+");
for(int i=0; i<pieces.length(); i++)
{
if(pieces[i].equalsIgnoreCase(sear))
{
System.out.println("Found: " +search);
}
else
{
System.out.println("No data found.");
}
}
Ok, here is my understanding of your program.
You search in the file file.txt the word CREATE.
To do so, you read each word in the file and if it is CREATE you print Found create.
The issue here is that for every word in the file, if it isn't CREATE you print No data found.
Instead you should wait for the end of the file and then if you haven't found it you will print the error message.
Try this :
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class readfile {
static String[] list;
static String sear = "CREATE";
public void search() throws IOException {
List<String> saveAllLinesForRewriting = new ArrayList<String>();
// Need to read file line by line
BufferedReader bufferedReader = new BufferedReader(new FileReader("file.txt"));
String saveLine;
while ((saveLine = bufferedReader.readLine()) != null) {
saveAllLinesForRewriting.add(saveLine);
}
bufferedReader.close();
// Check if your word exists
if (saveAllLinesForRewriting.toString().contains(sear)) {
System.out.println("Found: " + sear);
} else {
System.out.println("No data found.");
}
}
public static void main(String[] args) throws IOException {
readfile read = new readfile();
read.search();
}
}
Instead of reading file using scanner, first create a file resource to read by adding the below line
File file = new File("Full Path of file location");
before
Scannner scannedfile = new Scanner("file.txt");
and change the above line to
Scanner scannedfile = new Scanner(file);
rest your code is working fine.
The problem is that the scanner is scanning the String "file.txt" and not the file.
To fix this you have to do what amit28 says. Your finally code is as follows
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;
public class readfile {
static String[] list;
static String sear = "CREATE";
public void search() {
File f = new File("file.txt");
Scanner scannedFile;
try {
scannedFile = new Scanner(f);
while (scannedFile.hasNext()) {
String search = scannedFile.next();
System.out.println("SEARCH CONTENT:"+search);
if (search.equalsIgnoreCase(sear)) {
System.out.println("Found: " +search);
}
else {
System.out.println("No data found.");
}
}
} catch (FileNotFoundException e) {
// FIXME Auto-generated catch block
e.printStackTrace();
}
}
public static void main (String [] args) throws IOException {
readfile read = new readfile();
read.search();
}
}
I have a with the hentAntall method in my code below. It's supposed to find the search word inside a txt file. I don't get any sort of error. It just won't print out any of the two possible lines.
This method has to access a constructor first to get the search word, and then it has to find that search word in the txt file and add to count. The constructor gets the search word from another class. Like this new lolz("searchword").hentAntall();
(I apologize for the stupid naming in this program, but it's just a copy of one of my programs, and I'm just trying to correct it without screwing up the original.)
import java.io.File;
import java.util.Scanner;
public class lolz {
private String sokeord=null;
private int antall = 0;
// Constructor
lolz(String searchword) throws Exception{
this.sokeord = searchword;
}
//toString method, to print in the same format.
#Override
public String toString(){
return "\nSokeordet er: " + sokeord+ "\n";
}
// Gets the ammount of the searchword
public int hentAntall() throws Exception{
File file = new File("Hvorfor.txt");
Scanner readfile = new Scanner(file);
while (readfile.hasNextLine()){
String nextline = readfile.nextLine();
if (nextline.equalsIgnoreCase(sokeord)) {
antall ++;
System.out.println("Antallet av:" + sokeord + "er " + antall);
}
else {System.out.println("Error no such search word in the given text");}
}
return antall;
}
// void methode to increase the count of a searcheword.
void oekAntall() {
antall++;
}
}
This is the other class that calls on this method, and also give information to the constructor.
public class Main {
public static void main(String[] args) throws Exception {
new lolz("fungerer").hentAntall();
}}
Also tried some of the suggestions and they did not work, I only get a the message Process finished with exit code 0.
Your Issue:
You are trying to compare a Scanner variable with a String Variable?!!!
Explanation:
you try to compare content of Scanner which is
java.util.Scanner[delimiters=\p{javaWhitespace}+][position=0][match
valid=true][need input=false][source
closed=false][skipped=false][group separator=\,][decimal
separator=.][positive prefix=][negative prefix=\Q-\E][positive
suffix=][negative suffix=][NaN string=\Q�\E][infinity string=\Q∞\E]
with content of a String variable.
You do not read the each line with following
if (readfile.equals(sokeord)) {
You Should have
if (readfile.nextLine().equals(sokeord)) {
Instead of:
readfile.equals(sokeord)
Which is comparing an instance of type Scanner with a String (never going to be true). You need to read a line and compare that.
String line = readfile.nextLine();
if(line.equals(sokeord)){
Add a main method to your class:
public static void main(String[] args)
{
hentAntall();
}
You will have to make hentAntall() static or create an instance of lolz class and call it that way.
Also change:
while (readfile.hasNext()){
if (readfile.nextLine().contains(sokeord)) {
You need to actually read the input and then check if sokeord exists in the line or not.
Your hentAntall method should be like this:
public int hentAntall() throws Exception {
File file = new File("Hvorfor.txt");
Scanner readfile = new Scanner(file);
while (readfile.hasNextLine()) {
String word = readfile.next();
if (word.contains(sokeord)) {
antall++;
System.out.println("Antallet av:" + sokeord + "er " + antall);
} else {
System.out
.println("Error no such search word in the given text: ");
}
}
readfile.close();
return antall;
}
Don't forget to close the Scanner resource to avoid leaks.
I have the following code and would like to modify it to accept command line arguments instead of reading a file using scanner. Can you point me to some change I need to make in the code in order to do so ? Any help is appreciated. I will have a file called prgm.cmd and will execute it on UNIX as follows. prgm.cmd is the actual argument !
java Commander prgm.cmd
right now I am only able to have the program work by using
java Commander < prgm.cmd
CODE
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Commander
{
public static void main(String[] args)
{
Map<String,Integer> expression = new HashMap<String,Integer>();
ArrayList<String> list = new ArrayList<String>();
Scanner sc = new Scanner(System.in);
while(true)
{
list.add(sc.nextLine());
if(!sc.hasNextLine()) break;
}
ArrayList<String> tokens = new ArrayList<String>();
ArrayList<String> PRINT = new ArrayList<String>();
for(String element : list) {
StringTokenizer st = new StringTokenizer(element);
if(!element.startsWith("PRINT")) {
while(st.hasMoreTokens()) {
tokens.add(st.nextToken());
}
expression.put(tokens.get(0),Integer.parseInt(tokens.get(2)));
tokens.clear();
} else {
while(st.hasMoreTokens())
PRINT.add(st.nextToken());
System.out.println(expression.get(PRINT.get(1)));
PRINT.clear();
}
}
}
}
SAMPLE COMMAND FILE: PRGM.CMD
A = 6
C = 14
PRINT C
B = 12
C = 8
PRINT A
OUTPUT
14
6
public static void main(String[] args)
// ^^^^^^^^^^^^^
When you run your program with something like:
java progname arg1 arg2
the arguments appear in the string array handed to main(). You just extract them from there and do what you need.
The following small (but complete) program shows this in action. It will echo back your arguments, one per line:
public class Test {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++)
System.out.println (args[i]);
}
}
That's to get the commands as arguments to the program.
If, instead, you want to still have the commands in a file and just supply the file name to the program, you simply need to change your scanner to use a file based reader rather than System.in. The following program accepts a file name argument then echos it to the screen:
import java.io.FileInputStream;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
try {
Scanner sc = new Scanner (new FileInputStream(args[0]));
while (sc.hasNextLine())
System.out.println (sc.nextLine());
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
You can even make it selectable, like UNIX filter programs using - to indicate standard input.
If you want to use a file if provided but revert to standard input if not, you can do something like:
Scanner sc;
if (args.length > 0)
sc = new Scanner (new FileInputStream(args[0]));
else
sc = new Scanner (System.in);
// Now just use scanner as before