How to create array for text file searched by user input? - java

I am working on an assignment in which the program needs to read a file located by user input.
The file is scanned and an array is created.
The array stores in words as strings and outputs how many times a word has been used.
Then, the output is printed out into a new file.
package TestFileReader;
import java.io.*;
import java.util.*;
public class ReadFile
{
public static void main(String[] args)
{
//Prompts user for file by asking for its location
Scanner keys = new Scanner(System.in);
String fileName;
System.out.print("Enter file location, or 'Quit' to quit: ");
fileName = keys.nextLine();
Scanner textFile = null;
//try catch block for exception
try
{
textFile = new Scanner(new File(fileName));
}
catch(FileNotFoundException s)
{
System.out.println("File not found, confirm location: ");
}
//File will be read continuously until there is no next line
while(textFile.hasNextLine())
{
String contents = textFile.nextLine();
System.out.println(contents);
}
textFile.close();
//New Class for saving read into array
}
}

While I prepared the following example, Jan also answered properly that a HashMap can be used for this job:
HashMap<String,Integer> map=new HashMap<String,Integer>();
//File will be read continuously until there is no next line
while(textFile.hasNextLine())
{
String line = textFile.nextLine();
// Split line into words
String words[]=line.split("\\s+");
for (String word : words)
{
// Get current word count
Integer count=map.get(word);
if (count==null)
{
// Create a new counter for a new word
map.put(word,1);
}
else
{
// Increase existing word counter
map.put(word,count+1);
}
}
}
// Output result
for (Map.Entry<String,Integer> entry : map.entrySet())
{
System.out.println(entry.getKey()+": "+entry.getValue());
}
textFile.close();
The HashMap gets filled with an Integer counter for each word. If the word is found again, the counter will be increased. HashMaps are usually faster than nested loops over an array when you expect more than 20 entries.
Example inout file:
This is a test
This is another test
Wuff!
Example output:
a: 1
Wuff!: 1
test: 2
another: 1
This: 2
is: 2

Since Java 8 you could also use the Streams API to accomplish this task.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ReadFile {
public static void main(String[] args) {
//Prompts user for file by asking for its location
Scanner keys = new Scanner(System.in);
String fileName;
System.out.print("Enter file location, or 'Quit' to quit: ");
fileName = keys.nextLine();
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.flatMap(s -> Stream.of(s.split("\\W")))
.filter(s -> s != null && !s.isEmpty())
.collect(Collectors.toMap(s -> s, s -> 1, Integer::sum))
.forEach((k, v) -> System.out.println(k + ": " + v));
} catch (IOException e) {
System.out.println("Cannot read file: " + fileName);
}
}
}

Related

Reading from a file and storing the first Integer as a String and the rest as Integers

I am trying to read a file and store the individual integers, but make the first integer in the file into a String. I have been able to read the file but I am struggling to store the integers respectively. I want to use them within the program.
The file has three integers per line separated by a whitespace.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class arrayListStuffs2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter the file name: e.g \'test.txt\'");
String fileName = sc.nextLine();
try {
sc = new Scanner(new File(fileName));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
List<String> listS = new ArrayList<>();
List<Integer> listI = new ArrayList<>();
while (sc.hasNextLine()) {
listI.add(sc.nextInt());
}
System.out.println(listI);
}
}
You can use the following approach. Iterate lines, split it, take first as string and other two as integer (assuming that you have data as
1 2 3
4 5 6
7 8 9
):
List<String> listS = new ArrayList();
List<Integer> listI = new ArrayList();
// try with resource automatically close resources
try (BufferedReader reader = Files.newBufferedReader(Paths.get("res.txt")))
{
reader.lines().forEach(line -> {
String[] ints = line.split(" ");
listS.add(String.valueOf(ints[0]));
listI.add(Integer.parseInt(ints[1]));
listI.add(Integer.parseInt(ints[2]));
});
} catch (IOException e) {
e.printStackTrace();
}
Output is :

Count the number of times a set of characters appear in a file without BufferedReader

I am trying to count the number of times a string appears in a file. I want to find the number of times that "A, E, I, O, U" appears exactly in that order. Here is the text file:
AEIOU aeiou baeiboeu bbbaaaaaa beaeiou caeuoi ajejijoju aeioo
aeiOu ma me mi mo mu
take it OUT!
I want the method to then return how many times it is in the file. Any idea's on how I could go about doing this? The catch is I want to do this without using BufferedReader. I can simply just read the file using Scanner. Is there a way to do this?
I edited this and added the code I have so far. I don't think I am even close. I am pretty sure I need to use some nested loops to make this happen.
import java.util.*;
import java.io.*;
public class AEIOUCounter
{
public static final String DELIM = "\t";
public static void main(String[] args)
{
File filename = new File("aeiou.txt");
try
{
Scanner fileScanner = new Scanner(new File(filename));
while(fileScanner.hasNextLine())
{
System.out.println(fileScanner.nextLine());
}
}
catch(IOException e)
{
System.out.println(e);
}
catch(Exception e)
{
System.out.println(e);
}
fileScanner.close();
}
}
What you are doing now, is printing all the lines in the file.
fileScanner.hasNextLine()
fileScanner.nextLine()
But what you are looking for is filtering out separate words in the file:
Path path = Paths.get("/path/to/file");
Scanner sc = new Scanner(path);
int counter = 0;
while (sc.hasNext()) {
String word = sc.next();
if (word.equalsIgnoreCase("AEIOU")) {
counter += 1;
}
}
System.out.print("Number of words: " + counter);
Smurf's answer is great. It's worth mentioning that if you're using Java 8, you can avoid using a Scanner at all, and do this in a single expression:
long count = Files.lines(Paths.get("aeiou.txt"))
.flatMap(s -> Arrays.stream(s.split(" ")))
.filter(s -> s.equalsIgnoreCase("aeiou"))
.count();

[Ljava.lang.String;#50f6d9ca [duplicate]

This question already has answers here:
Why does println(array) have strange output? ("[Ljava.lang.String;#3e25a5") [duplicate]
(6 answers)
Closed 8 years ago.
What does this mean?
I am trying to print an array pf strings that is about 570,000 strings long...I believe that is what this relates to.
It prints out when I run my program. Ignore the commented out code; this program is a work in progress.
package nGram;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
public class HashMapFun {
public static void main(String[] agrs) throws FileNotFoundException {
HashMap <String, Integer> wordFrequency = new HashMap <String, Integer> ();
String bookContent = getFile("AtlasShrugged.txt");
//Remove punctuation marks from string "bookContent"
//Split the words using spaces
String[] words = bookContent.split(" ");
System.out.println(words);
// bookContent.replace(".", "");
// bookContent.replace("!", "");
// bookContent.replace("?", "");
// bookContent.replace("(", "");
// bookContent.replace(")", "");
// bookContent.replace("-", "");
// bookContent.replace(";", "");
//Go to every word in the list
for (String word : words) {
//If I have already added the word to the frequency map
if (wordFrequency.containsKey(word)) {
int freq = wordFrequency.get(word);
freq = freq + 1;
wordFrequency.put(word, freq );
}
else {
//If not, add to HashMap
wordFrequency.put(word, 1);
}
}
// Iterator iterator = wordFrequency.keySet().iterator();
//
// while (iterator.hasNext()) {
// String key = iterator.next().toString();
// String value = wordFrequency.get(key).toString();
//
// System.out.println(key + " " + value);
// PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
// System.setOut(out);
}
//}
public static String getFile(String path) {
// Make a File object to represent this file at the path
File f = new File(path);
// Do the code in the try, and if it fails do the catch code
try {
// Make a scanner to read the file
Scanner fileScanner = new Scanner(f);
// Make a StringBuilder to create the file content
StringBuilder content = new StringBuilder();
// While the file scanner still has a line of input
while (fileScanner.hasNextLine()) {
// Append the next line of file input
content.append(fileScanner.nextLine());
// Append a newline character.
content.append("\n");
}
// Return whatever is in the StringBuilder
return content.toString();
}
// Catch any error that may occur in the above try statement
catch (FileNotFoundException e) {
System.out.println("Didn't find the file.");
}
return ""; // If all else fails, return an empty string.
}
}
java.lang.String;#50f6d9ca
What that means is that you are trying to print the memory location that was allocated from your words array which was printed here:
System.out.println(words);
You are printing a string array, not a string.
This is just the way Java prints arrays. To see each string, try
Arrays.toString(yourArray)
By the way, see this Stack Overflow answer to see the reason why you are seeing what you are seeing.

How do I accept a command and a filename in the same input string in java?

Basically this is what my input will look like:
C:> ltf sample.txt
Then Shell v2.0(program) creates a sample.txt file in C drive.
I have explored the split() function but I have to validate my input from the commands stored in my array. So I need to "store" the file name in my array as well. I know this isn't plausible as the file names would vary. Basically what I am trying to ask is, how do I accept a command and a file name together? This is my current code just to give you an idea of what I am trying to do
package assignment311;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import java.util.*;
import javax.swing.JOptionPane;
public class assignment {
/*Data Members*/
public static String[] myData;
public static String CurrentPath;
/*Methods*/
public assignment()
{
myData=new String[13];
myData[0]="ls";
myData[1]="ls -la";
myData[2]="less";
myData[3]="gd";
myData[4]="md";
myData[5]="rnd";
myData[6]="del";
myData[7]="hd";
myData[8]="uhd";
myData[9]="ltf";
myData[10]="nbc";
myData[11]="gdb ";
myData[12]="Tedit";
//initialise currentpath
CurrentPath="C:/";
}
public static void main(String[] args)
{
//initialise data by constructing an object of class
assignment obj=new assignment();
String userInput="";
do
{
//while
//get user input
System.out.print(" "+CurrentPath+"> ");
Scanner scan=new Scanner(System.in);
userInput=scan.nextLine();
String[] stringarray = userInput.split(" ");
/// boolean variable to display information about command validity
boolean isFound=false;
for(int j=0;j<myData.length;j++)
{
if(userInput.equals(myData[j]))
{
isFound=true;
if(stringarray[0].equals("ls"))
{
obj.Run_Ls();
}
if(stringarray[0].equals("gd"))
{
//ask user to enter a folder name
System.out.println("enter a valid folder name");
//get input
String fdname=scan.nextLine();
//get all folders name
File myfile=new File(CurrentPath);
String[] allfiles=myfile.list();
// match user input with folder names
boolean isdirthere=false;
for(int k=0;k<allfiles.length;k++)
{
if(fdname.equals(allfiles[k]))
{
CurrentPath=CurrentPath+"/"+allfiles[k];
isdirthere=true;
}
}
if(!isdirthere)
{
System.out.println("Invalid Folder Name");
}
}
if(userInput.equals("ltf"))
{
System.out.println("Enter valid file name");
String filename=scan.nextLine();
final Formatter x;
try
{
x = new Formatter(filename);
System.out.println("File Created");
}
catch (Exception e)
{
System.out.println("Error man");
}
}
if(userInput.equals("nbc"))
{
}
}
}
if(!isFound)
{
System.out.println("Invalid Command");
}
// scan.close();
//end of while
}
while(!userInput.equals("exit"));
}
public void Run_Ls()
{
File obj=new File(CurrentPath);
String[] ls_result=obj.list();
for(int i=0;i<ls_result.length;i++)
{
System.out.println(ls_result[i]);
}
}
}
Instead of storing simple strings, store lists or arrays of strings:
String[][] myData = {
{"ls"},
{"ls", "-la"}
};
This way, you can preserve the structure of your commands (i.e. command name and all the arguments) without having to make guesses what a space in there might mean.
You need command and filename on the same line. Instead of checking for userInput.equals, you could try using userInput.startsWith, this will return true when your input starts with a command which matches the array myData.
You may run into issues where there are two command which have the same starting alphabets like:
myData[0]="ls";
myData[1]="ls -la";
You could change the above to:
myData[0]="ls -la";
myData[1]="ls ";
After you find a command which matches your list, you can do a substring where
String fileName = userInput.subString(myData[x].length).trim();
For a string "cmd ", the above operation will return only .
this will give you the flexibility of not worrying about the different file formats.
You may need to add some validation to the fileName variable though.

Count Word Pairs Java

I have this programming assignment and it is the first time in our class that we are writing code in Java. I have asked my instructor and could not get any help.
The program needs to count word pairs from a file, and display them like this:
abc:
hec, 1
That means that there was only one time in the text file that "abc" was followed by "hec". I have to use the Collections Framework in java. Here is what I have so far.
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.ArrayList;
// By default, this code will get its input data from the Java standard input,
// java.lang.System.in. To allow input to come from a file instead, which can be
// useful when debugging your code, you can provide a file name as the first
// command line argument. When you do this, the input data will come from the
// named file instead. If the input file is in the project directory, you will
// not need to provide any path information.
//
// In BlueJ, specify the command line argument when you call main().
//
// In Eclipse, specify the command line argument in the project's "Run Configuration."
public class Assignment1
{
// returns an InputStream that gets data from the named file
private static InputStream getFileInputStream(String fileName)
{
InputStream inputStream;
try {
inputStream = new FileInputStream(new File(fileName));
}
catch (FileNotFoundException e) { // no file with this name exists
System.err.println(e.getMessage());
inputStream = null;
}
return inputStream;
}
public static void main(String[] args)
{
// Create an input stream for reading the data. The default is
// System.in (which is the keyboard). If there is an arg provided
// on the command line then we'll use the file instead.
InputStream in = System.in;
if (args.length >= 1) {
in = getFileInputStream(args[0]);
}
// Now that we know where the data is coming from we'll start processing.
// Notice that getFileInputStream could have generated an error and left "in"
// as null. We should check that here and avoid trying to process the stream
// data if there was an error.
if (in != null) {
// Using a Scanner object to read one word at a time from the input stream.
#SuppressWarnings("resource")
Scanner sc = new Scanner(in);
String word;
System.out.printf("CS261 - Assignment 1 - Matheus Konzen Iser%n%n");
// Continue getting words until we reach the end of input
List<String> inputWords = new ArrayList<String>();
Map<String, List<String>> result = new HashMap<String, List<String>>();
while (sc.hasNext()) {
word = sc.next();
if (!word.equals("---")) {
// do something with each word in the input
// replace this line with your code (probably more than one line of code)
inputWords.add(word);
}
for(int i = 0; i < inputWords.size() - 1; i++){
// Create references to this word and next word:
String thisWord = inputWords.get(i);
String nextWord = inputWords.get(i+1);
// If this word is not in the result Map yet,
// then add it and create a new empy list for it.
if(!result.containsKey(thisWord)){
result.put(thisWord, new ArrayList<String>());
}
// Add nextWord to the list of adjacent words to thisWord:
result.get(thisWord).add(nextWord);
}
//OUTPUT
for(Entry e : result.entrySet()){
System.out.println(e.getKey() + ":");
// Count the number of unique instances in the list:
Map<String, Integer>count = new HashMap<String, Integer>();
List<String>words = (List)e.getValue();
for(String s : words){
if(!count.containsKey(s)){
count.put(s, 1);
}
else{
count.put(s, count.get(s) + 1);
}
}
// Print the occurances of following symbols:
for(Entry f : count.entrySet()){
System.out.println(" " + f.getKey() + ", " + f.getValue());
}
}
}
System.out.printf("%nbye...%n");
}
}
}
The problem that I'm having now is that it is running through the loop below way too many times:
if (!word.equals("---")) {
// do something with each word in the input
// replace this line with your code (probably more than one line of code)
inputWords.add(word);
}
Does anyone have any ideas or tips on this?
I find this part confusing:
while (sc.hasNext()) {
word = sc.next();
if (!word.equals("---")) {
// do something with each word in the input
// replace this line with your code (probably more than one line of code)
inputWords.add(word);
}
for(int i = 0; i < inputWords.size() - 1; i++){
I think you probably mean something more like this:
// Add all words (other than "---") into inputWords
while (sc.hasNext()) {
word = sc.next();
if (!word.equals("---")) {
inputWords.add(word);
}
}
// Now iterate over inputWords and process each word one-by-one
for (int i = 0; i < inputWords.size(); i++) {
It looks like you're trying to read all the words into inputWords first and then process them, while your code iterates through the list after every word that you add.
Note also that your condition in the for loop is overly-conservative, so you'll miss the last word. Removing the - 1 will give you an index for each word.

Categories