Storing input into file - java

I am having an issue trying to search a text file for the exact input that a user enters. I want to output the sentence not only by direct user input but i want the program to recognize some word(s) that would signal the desired text. I got searching for the keyword part down pack and working but i am only able to search the text based on the keyword. I want to search based on the keyword and the entire inputted sentence. For example if the keyword is e-mail and the user enter's what is mars e-mail? and the text file contains "mars e-mail is mars3433#aol.com, john e-mail is anonymous" i want to output mars e-mail is ... instead of both sentences. I am completely stuck trying to figure out this issue, Can anyone help me?
public static class DicEntry {
String key;
String[] syns;
Pattern pattern;
public DicEntry(String key, String... syns) {
this.key = key;
this.syns = syns;
pattern = Pattern.compile(".*(?:"
+ Stream.concat(Stream.of(key), Stream.of(syns))
.map(x -> "\\b" + Pattern.quote(x) + "\\b")
.collect(Collectors.joining("|")) + ").*");
}
}
public static void removedata(String s) throws IOException {
File f = new File("data.txt");
File f1 = new File("data2.txt");
BufferedReader input = new BufferedReader(new InputStreamReader(
System.in));
BufferedReader br = new BufferedReader(new FileReader(f));
PrintWriter pr = new PrintWriter(f1);
String line;
while ((line = br.readLine()) != null) {
if (line.contains(s)) {
System.out.println("Enter new Text :");
String newText = input.readLine();
line = newText;
System.out.println("Thank you, Have a good Day!");
}
pr.println(line);
}
br.close();
pr.close();
input.close();
Files.move(f1.toPath(), f.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
public static void parseFile(String s) throws IOException {
File file = new File("data.txt");
Scanner forget = new Scanner(System.in);
Scanner scanner = new Scanner(file);
int flag_found = 0;
while (scanner.hasNextLine()) {
final String lineFromFile = scanner.nextLine();
if (lineFromFile.contains(s)) {
// a match!
System.out.println(lineFromFile);
flag_found = 1;
System.out
.println(" Would you like to update this information ? ");
String yellow = forget.nextLine();
if (yellow.equals("yes")) {
removedata(lineFromFile);
} else if (yellow.equals("no")) {
System.out.println("Have a good day");
// break;
}
}
}
if (flag_found == 0) {// input is not found in the txt file so
// flag_found remains 0
writer();
}
}
public static void writer() {
Scanner Keyboard = new Scanner(System.in);
Scanner input = new Scanner(System.in);
File file = new File("data.txt");
try (BufferedWriter wr = new BufferedWriter(new FileWriter(
file.getAbsoluteFile(), true))) { // Creates a writer object
// called wr
// file.getabsolutefile
// takes the filename and
// keeps on storing the old
System.out.println("I Do not know, Perhaps you want to teach me?"
+ "..."); // data
while ((Keyboard.hasNext())) {
String lines = Keyboard.nextLine();
System.out.print(" is this correct ? ");
String go = input.nextLine();
if (go.equals("no")) {
System.out.println("enter line again");
lines = Keyboard.nextLine();
System.out.print(" is this correct ? ");
go = input.nextLine();
}
else if (go.equals("yes")) {
wr.write(lines);
// wr.write("\n");
wr.newLine();
wr.close();
}
System.out.println("Thankk you");
break;
}
} catch (IOException e) {
System.out.println(" cannot write to file " + file.toString());
}
}
private static List<DicEntry> populateSynonymMap() {
List<DicEntry> responses = new ArrayList<>();
responses.add(new DicEntry("student", "pupil", "scholar"));
responses.add(new DicEntry("office", "post", "room"));
responses.add(new DicEntry("topics", "semester talk"));
return responses;
}
public static void getinput() throws IOException {
List<DicEntry> synonymMap = populateSynonymMap(); // populate the map
Scanner scanner = new Scanner(System.in);
String input = null;
/* End Initialization */
System.out.println("Welcome ");
System.out.println("What would you like to know?");
System.out.print("> ");
input = scanner.nextLine().toLowerCase();
String[] inputs = input.split(" ");
int flag_found = 0;
for (DicEntry entry : synonymMap) { // iterate over each word of the
// sentence.
if (entry.pattern.matcher(input).matches()) {
// System.out.println(entry.key);
parseFile(entry.key);
flag_found = 1;// Input is found
}
}
if (flag_found == 0) {// input is not found in the txt file so
// flag_found remains 0
writer();
}
}
public static void main(String args[]) throws ParseException, IOException {
/* Initialization */
getinput();
}
}
So my methods work like this, the parse file method searching the text file for the keyword in the sentence. My writer( ) writes to the file if the input is not found and my remove data ( ) erases the line and updates it with the new string upon user request. and get input is just a method to get information from the scanner.

In my opinion, additional obstacle is fact, that some word can repeat in unrelated sentences. My solution seems to be quite long for me, but it works. However when I test it, I didn't use your dicEntry. It is impossible to hard-code all synonyms, so you should reconsider this approach.
I added one class, jast as data holder for int repetition variable (see below) and particular sentence:
public class Pair {
int repetitions;
String sentence;
public Pair(int rep, String string){
repetitions = rep;
sentence = string;
}
public int getRepetitions() {
return repetitions;
}
public String getSentence() {
return sentence;
}
}
Then I wrote a method, which loop through input sentence, and file content, looking for sentence from file, in which most inputs words repeted. I pretty sure, it is not most efficient way, but I don't know another :P.
public static String getMostAppropriate(String[] input) throws IOException{
File file = new File("data.txt");
Scanner scanner = new Scanner(file);
ArrayList<Pair> pairs = new ArrayList<>();
int repetitions = 0;
while (scanner.hasNextLine()) {
String newLine = scanner.nextLine();
String[] line = newLine.split(","); // this regex depends on your file format style,
String oneSentence = "";
for(String sentence : line){ // for sentence in file lines
for(String string : sentence.split(" ")){ // for words in these sentences
for(String word : input){ // for words from input
if(word.equals(string)){
repetitions += 1;
oneSentence = sentence;
}
}
}
pairs.add(new Pair(repetitions,oneSentence));
repetitions = 0;
}
}
return mostCommon(pairs);
}
The argument is String[] inputs form your getInput method. In return statement I called another new method, which looks for sentences with most repetitions:
public static String mostCommon(ArrayList<Pair> pairs){
Pair max = new Pair(0,"");
String result = "";
for(Pair pair : pairs){
if(pair.getRepetitions() > max.getRepetitions()){
result = pair.getSentence();
max = pair;
}else if(pair.getRepetitions()==max.getRepetitions()){
result += "; " + pair.getSentence();
}
}
return result;
}
If some sentences have same number of repetitions, it returns both(or more) connected into one sentence (sentence; sentence; etc.).
Implementation into your code I left for you, if you are interested.
As I said, I didn't use your dicEntry, still you can add it as additional loop, but chacking whole dictionary will not be too effective with my method.
Also, if I were you, I would divide some of your methods into smaller one, I mean like: read file in one, ask for additional input in another. Because it is easier to implement changes this way. You don't need to keep eye on whole method, just arguments they pass to each other.
I hope you will find something useful in my post.

Related

How to replace the first line of a txt document

I would like to replace the first line of the document Vokabeln.txt, where the number of vocabularies is stored, so that when a vocabulary is added, the number is increased by one.
Thanks for helping me.
import java.io.*;
public class Vokabeltrainer
{
private String file;
private String line;
private int anzahlVokabeln;
private boolean status = true;
Scanner sc = new Scanner(System.in);
private ArrayList <Vokabel> Vokabelliste;
public Vokabeltrainer()
{
this.file = "";
this.Vokabelliste = new ArrayList<Vokabel>();
}
public void main() throws IOException
{
System.out.println("Vokabeln.txt");
this.file = ("Vokabeln.txt");
try (BufferedReader br = new BufferedReader(new FileReader(file)))
{
line = br.readLine();
anzahlVokabeln = Integer.parseInt(line);
for(int i = 0;i < anzahlVokabeln; i++)
{
line = br.readLine();
this.Vokabelliste.add(new Vokabel(line.split("\\s+")[0],line.split("\\s+")[1]));
}
}
while(status==true)
{
System.out.println("Was willst du machen \n-Vokabel hinzufügen\n-Vokabel enfernen\n-Vokabeln Abfragen\n-Programm Quit");
String line = sc.nextLine();
if(line.equals("one")||line.equals("Add vocabulary"))
{
Vokabelhinzufügen();
}
else if(line.equals("two")||line.equals("Remove vocabulary"))
{
}
else if(line.equals("three")||line.equals("Vokabeln Abfragen"))
{
}
else if(line.equals("four")||line.equals("Quit"))
{
status = false;
//Maybe Statistics from the User
}
else
{
System.out.println("This option doesnt exists.");
}
}
}
public void Vokabelhinzufügen()
{
boolean vokabelhinzustatus = true;
String Vokabel = "";
while(vokabelhinzustatus==true)
{
System.out.println("Please enter the vocabulary now. (Hallo Hello)");
Vokabel = sc.nextLine();
try(PrintWriter output = new PrintWriter(new FileWriter("Vokabeln.txt",true)))
{
output.printf("%s\r\n", Vokabel.toLowerCase());
String after = String.valueOf(anzahlVokabeln+1);
String before = String.valueOf(anzahlVokabeln);
//At this point the replace has to be. before is the number before the translation was added and after is after the translation was added.
}
catch (Exception e) {}
System.out.println("Vocabulary Successfully Added");
System.out.println("Exit Add Vocabulary?");
String line = sc.nextLine();
if(line.equals("yes"))
{
break;
}
}
}
public void Vokabelentfernen()
{
}
}
Not an answer to your question;
a design suggestion instead.
It appears that you have a file in which you store things
(perhaps Vokablin)
and each thing in the file is structured the same,
but contains different details.
Do not store the count in the file.
Instead,
Just store things in the file and read them all.
If you must,
add a marker at the end of the file that indicates "end of stuff".
For, reasons, you might want to store a count of things in the file.
If that is the case,
store the count as part of the end-of-file marker.
If you use this technique,
your add-to-the-file algorithm becomes this:
Read a line.
Is the line a thing?
if yes, write it,
if no, parse the end-of-file marker, increment the count, and write the end-of-file marker.

scanner.useDelimiter not working on web based CSV file

So I am a beginner with Java and I am having a hard time learning so please be easy. I am working on a solution that would take the users input of UK currency and find the exchange rate for a user input country. Don't know that I am on the right track or not but below is the code for after the user inputs the currency amount and country to convert to. I am needing to read a web based CSV file and parse in into a POJO but I can not get the in.useDelimiter to work.
public static Double findExchangeRateAndConvert(String currencyType, double amount) throws IOException {
URL url = new URL("https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/842362/exrates-monthly-1119.csv");
try (var in = new Scanner(
new BufferedReader(
new InputStreamReader(url.openStream())))) {
var line = "";
in.useDelimiter(",");
while (in.hasNextLine()) {
line = in.nextLine();
System.out.println(line);
if (line.contains(currencyType)) {
System.out.println("I found it.");
System.exit(0);
}
}
}
return null;
}
Use your scanner to read a line at a time, and then split the line based on regexp. Line by line processing is a good approach as it simple to understand what is happening.
public class Main {
public static void main(String[] args) throws IOException {
Double d = Main.findExchangeRateAndConvert("USD", 12);
System.out.println("d=" + d);
}
public static Double findExchangeRateAndConvert(String currencyType, double amount) throws IOException {
URL url = new URL("https://www.gov.uk/government/uploads/system/uploads/attachment_data/file/842362/exrates-monthly-1119.csv");
try (var in = new Scanner(
new BufferedReader(
new InputStreamReader(url.openStream())))) {
var line = "";
in.useDelimiter(",");
while (in.hasNextLine()) {
line = in.nextLine();
System.out.println(line);
String[] splitLine = line.split(",");
if (splitLine[2].equals(currencyType)) {
System.out.println("I found it.");
return Double.valueOf(splitLine[3]);
}
}
}
return null;
}
}

my java program is not working after I execute file io

Hello so i have an assignment and my code is not working. I ask a user to input a filename and after that it freezes and does not process the number of lines. im doing something wrong but im not sure what? can someone please help me im really desperate this part is crashing my whole program and i might fail and i dont know who to ask :( for help
public static void fileReader()
{
Scanner sc = new Scanner(System.in);
int catNum;
int dogNum;
int fishNum;
String fileName;
System.out.println("Please enter the Name of the file you want to read in
from");
fileName = sc.nextLine();
System.out.println("this is the file name --> "+fileName);
catNum = TestFile.getNum(fileName, "cat");
dogNum = TestFile.getNum(fileName, "dog");
fishNum = TestFile.getNum(fileName, "fish");
System.out.println("THE CAT IS" +catNum);
System.out.println("THE DOG IS" +dogNum);
System.out.println("THE FISH IS" +fishNum);
}
i dont see anything wrong after i ask for the file name it freezes
public static int getNum (String fileName, String word) {
Scanner sc = new Scanner(System.in);
int lineNum = 0;
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
String line;
try {
fileStrm = new FileInputStream (fileName);
rdr = new InputStreamReader (fileStrm);
bufRdr = new BufferedReader (rdr);
line = bufRdr.readLine();
while (line != null)
{
String firstWord = processString(line);
if(firstWord.equalsIgnoreCase(word)) //this submodule i going to get the number to create each array like e.g. how many states so that it can create it in country object
{
lineNum++;
line = bufRdr.readLine() ;
}
}
fileStrm.close();
}
catch (IOException e)
{
if (fileStrm != null)
{
try
{
fileStrm.close();
}
catch(IOException ex2)
{
System.out.println("This is Error");
}
}
System.out.println("error reading file !!" +e.getMessage());
}
return lineNum; }
the file looks something like this (each line is like this):
CAT:NAME=doopie:SHORTNAME=doop:LANGUAGE=English:AREA=America:POPULATION=2222:POPREF=Census2016
Look at this while loop:
while (line != null)
{
String firstWord = processString(line);
if(firstWord.equalsIgnoreCase(word)) //this submodule i going to get the number to create each array like e.g. how many states so that it can create it in country object
{
lineNum++;
line = bufRdr.readLine() ;
}
}
If firstWord.equalsIgnoreCase(word) returns false, then what will happen? The value of line will never be updated and the loop will never exit.

Check if a file contains strings and create an array for new strings

I need to create a method that will read the file, and check each word in the file. Each new word in the file should be stored in a string array. The method should be case insensitive. Please help.
The file says the following:
Ask not what your country can do for you
ask what you can do for your country
So the array should only contain: ask, not, what, your, country, can, do, for, you
import java.util.*;
import java.io.*;
public class TextAnalysis {
public static void main (String [] args) throws IOException {
File in01 = new File("a5_testfiles/in01.txt");
Scanner fileScanner = new Scanner(in01);
System.out.println("TEXT FILE STATISTICS");
System.out.println("--------------------");
System.out.println("Length of the longest word: " + longestWord(fileScanner));
System.out.println("Number of words in file wordlist: " );
countWords();
System.out.println("Word-frequency statistics");
}
public static String longestWord (Scanner s) {
String longest = "";
while (s.hasNext()) {
String word = s.next();
if (word.length() > longest.length()) {
longest = word;
}
}
return (longest.length() + " " + "(\"" + longest + "\")");
}
public static void countWords () throws IOException {
File in01 = new File("a5_testfiles/in01.txt");
Scanner fileScanner = new Scanner(in01);
int count = 0;
while(fileScanner.hasNext()) {
String word = fileScanner.next();
count++;
}
System.out.println("Number of words in file: " + count);
}
public static int wordList (int words) {
File in01 = new File("a5_testfiles/in01.txt");
Scanner fileScanner = new Scanner(in01);
int size = words;
String [] list = new String[size];
for (int i = 0; i <= size; i++) {
while(fileScanner.hasNext()){
if(!list[].contains(fileScanner.next())){
list[i] = fileScanner.next();
}
}
}
}
}
You could take advantage of my following code snippet (it will not store the duplicate words)!
File file = new File("names.txt");
FileReader fr = new FileReader(file);
StringBuilder sb = new StringBuilder();
char[] c = new char[256];
while(fr.read(c) > 0){
sb.append(c);
}
String[] ss = sb.toString().toLowerCase().trim().split(" ");
TreeSet<String> ts = new TreeSet<String>();
for(String s : ss)
ts.add(s);
for(String s : ts){
System.out.println(s);
}
And the output is:
ask
can
country
do
for
not
what
you
your
You could always just try:
List<String> words = new ArrayList<String>();
//read lines in your file all at once
List<String> allLines = Files.readAllLines(yourFile, Charset.forName("UTF-8"));
for(int i = 0; i < allLines.size(); i++) {
//change each line from your file to an array of words using "split(" ")".
//Then add all those words to the list "words"
words.addAll(Arrays.asList(allLines.get(i).split(" ")));
}
//convert the list of words to an array.
String[] arr = words.toArray(new String[words.size()]);
Using Files.readAllLines(yourFile, Charset.forName("UTF-8")); to read all the lines of yourFile is much cleaner than reading each individually. The problem with your approach is that you're counting the number of lines, not the number of words. If there are multiple words on one line, your output will be incorrect.
Alternatively, if you do not use Java 7, you can create a list of lines as follows and then count the words at the end (as opposed to your approach in countWords():
List<String> allLines = new ArrayList<String>();
Scanner fileScanner = new Scanner(yourFile);
while (fileScanner.hasNextLine()) {
allLines.add(scanner.nextLine());
}
fileScanner.close();
Then split each line as shown in the previous code and create your array. Also note that you should use a try{} catch block around your scanner rather than throws ideally.

Method to find string inside of the text file. Then getting the following lines up to a certain limit

So this is what I have so far :
public String[] findStudentInfo(String studentNumber) {
Student student = new Student();
Scanner scanner = new Scanner("Student.txt");
// Find the line that contains student Id
// If not found keep on going through the file
// If it finds it stop
// Call parseStudentInfoFromLine get the number of courses
// Create an array (lines) of size of the number of courses plus one
// assign the line that the student Id was found to the first index value of the array
//assign each next line to the following index of the array up to the amount of classes - 1
// return string array
}
I know how to find if a file contains the string I am trying to find but I don't know how to retrieve the whole line that its in.
This is my first time posting so If I have done anything wrong please let me know.
You can do something like this:
File file = new File("Student.txt");
try {
Scanner scanner = new Scanner(file);
//now read the file line by line...
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
lineNum++;
if(<some condition is met for the line>) {
System.out.println("ho hum, i found it on line " +lineNum);
}
}
} catch(FileNotFoundException e) {
//handle this
}
Using the Apache Commons IO API https://commons.apache.org/proper/commons-io/ I was able to establish this using FileUtils.readFileToString(file).contains(stringToFind)
The documentation for this function is at https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/FileUtils.html#readFileToString(java.io.File)
Here is a java 8 method to find a string in a text file:
for (String toFindUrl : urlsToTest) {
streamService(toFindUrl);
}
private void streamService(String item) {
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.filter(lines -> lines.contains(item))
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
When you are reading the file, have you considered reading it line by line? This would allow you to check if your line contains the file as your are reading, and you could then perform whatever logic you needed based on that?
Scanner scanner = new Scanner("Student.txt");
String currentLine;
while((currentLine = scanner.readLine()) != null)
{
if(currentLine.indexOf("Your String"))
{
//Perform logic
}
}
You could use a variable to hold the line number, or you could also have a boolean indicating if you have passed the line that contains your string:
Scanner scanner = new Scanner("Student.txt");
String currentLine;
int lineNumber = 0;
Boolean passedLine = false;
while((currentLine = scanner.readLine()) != null)
{
if(currentLine.indexOf("Your String"))
{
//Do task
passedLine = true;
}
if(passedLine)
{
//Do other task after passing the line.
}
lineNumber++;
}
This will find "Mark Sagal" in Student.txt. Assuming Student.txt contains
Student.txt
Amir Amiri
Mark Sagal
Juan Delacruz
Main.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
final String file = "Student.txt";
String line = null;
ArrayList<String> fileContents = new ArrayList<>();
try {
FileReader fReader = new FileReader(file);
BufferedReader fileBuff = new BufferedReader(fReader);
while ((line = fileBuff.readLine()) != null) {
fileContents.add(line);
}
fileBuff.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(fileContents.contains("Mark Sagal"));
}
}
I am doing something similar but in C++. What you need to do is read the lines in one at a time and parse them (go over the words one by one). I have an outter loop that goes over all the lines and inside that is another loop that goes over all the words. Once the word you need is found, just exit the loop and return a counter or whatever you want.
This is my code. It basically parses out all the words and adds them to the "index". The line that word was in is then added to a vector and used to reference the line (contains the name of the file, the entire line and the line number) from the indexed words.
ifstream txtFile;
txtFile.open(path, ifstream::in);
char line[200];
//if path is valid AND is not already in the list then add it
if(txtFile.is_open() && (find(textFilePaths.begin(), textFilePaths.end(), path) == textFilePaths.end())) //the path is valid
{
//Add the path to the list of file paths
textFilePaths.push_back(path);
int lineNumber = 1;
while(!txtFile.eof())
{
txtFile.getline(line, 200);
Line * ln = new Line(line, path, lineNumber);
lineNumber++;
myList.push_back(ln);
vector<string> words = lineParser(ln);
for(unsigned int i = 0; i < words.size(); i++)
{
index->addWord(words[i], ln);
}
}
result = true;
}
Here is the code of TextScanner
public class TextScanner {
private static void readFile(String fileName) {
try {
File file = new File("/opt/pol/data22/ds_data118/0001/0025090290/2014/12/12/0029057983.ds");
Scanner scanner = new Scanner(file);
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("usage: java TextScanner1"
+ "file location");
System.exit(0);
}
readFile(args[0]);
}
}
It will print text with delimeters

Categories