Storing an array of strings without initializing the size - java

Background: This program reads in a text file and replaces a word in the file with user input.
Problem: I am trying to read in a line of text from a text file and store the words into an array.
Right now the array size is hard-coded with an number of indexes for test purposes, but I want to make the array capable of reading in a text file of any size instead.
Here is my code.
public class FTR {
public static Scanner input = new Scanner(System.in);
public static Scanner input2 = new Scanner(System.in);
public static String fileName = "C:\\Users\\...";
public static String userInput, userInput2;
public static StringTokenizer line;
public static String array_of_words[] = new String[19]; //hard-coded
/* main */
public static void main(String[] args) {
readFile(fileName);
wordSearch(fileName);
replace(fileName);
}//main
/*
* method: readFile
*/
public static void readFile(String fileName) {
try {
FileReader file = new FileReader(fileName);
BufferedReader read = new BufferedReader(file);
String line_of_text = read.readLine();
while (line_of_text != null) {
System.out.println(line_of_text);
line_of_text = read.readLine();
}
} catch (Exception e) {
System.out.println("Unable to read file: " + fileName);
System.exit(0);
}
System.out.println("**************************************************");
}
/*
* method: wordSearch
*/
public static void wordSearch(String fileName) {
int amount = 0;
System.out.println("What word do you want to find?");
userInput = input.nextLine();
try {
FileReader file = new FileReader(fileName);
BufferedReader read = new BufferedReader(file);
String line_of_text = read.readLine();
while (line_of_text != null) { //there is a line to read
System.out.println(line_of_text);
line = new StringTokenizer(line_of_text); //tokenize the line into words
while (line.hasMoreTokens()) { //check if line has more words
String word = line.nextToken(); //get the word
if (userInput.equalsIgnoreCase(word)) {
amount += 1; //count the word
}
}
line_of_text = read.readLine(); //read the next line
}
} catch (Exception e) {
System.out.println("Unable to read file: " + fileName);
System.exit(0);
}
if (amount == 0) { //if userInput was not found in the file
System.out.println("'" + userInput + "'" + " was not found.");
System.exit(0);
}
System.out.println("Search for word: " + userInput);
System.out.println("Found: " + amount);
}//wordSearch
/*
* method: replace
*/
public static void replace(String fileName) {
int amount = 0;
int i = 0;
System.out.println("What word do you want to replace?");
userInput2 = input2.nextLine();
System.out.println("Replace all " + "'" + userInput2 + "'" + " with " + "'" + userInput + "'");
try {
FileReader file = new FileReader(fileName);
BufferedReader read = new BufferedReader(file);
String line_of_text = read.readLine();
while (line_of_text != null) { //there is a line to read
line = new StringTokenizer(line_of_text); //tokenize the line into words
while (line.hasMoreTokens()) { //check if line has more words
String word = line.nextToken(); //get the word
if (userInput2.equalsIgnoreCase(word)) {
amount += 1; //count the word
word = userInput;
}
array_of_words[i] = word; //add word to index in array
System.out.println("WORD: " + word + " was stored in array[" + i + "]");
i++; //increment array index
}
//THIS IS WHERE THE PRINTING HAPPENS
System.out.println("ARRAY ELEMENTS: " + Arrays.toString(array_of_words));
line_of_text = read.readLine(); //read the next line
}
BufferedWriter outputWriter = null;
outputWriter = new BufferedWriter(new FileWriter("C:\\Users\\..."));
for (i = 0; i < array_of_words.length; i++) { //go through the array
outputWriter.write(array_of_words[i] + " "); //write word from array to file
}
outputWriter.flush();
outputWriter.close();
} catch (Exception e) {
System.out.println("Unable to read file: " + fileName);
System.exit(0);
}
if (amount == 0) { //if userInput was not found in the file
System.out.println("'" + userInput2 + "'" + " was not found.");
System.exit(0);
}
}//replace
}//FTR

You can use java.util.ArrayList (which dynamically grows unlike an array with fixed size) to store the string objects (test file lines) by replacing your array with the below code:
public static List<String> array_of_words = new java.util.ArrayList<>();
You need to use add(string) to add a line (string) and get(index) to retrieve the line (string)
Please refer the below link for more details:
http://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html

You may want to give a try to ArrayList.
In Java normal arrays cannot be initialized without giving initial size and they cannot be expanded during run time. Whereas ArrayLists have resizable-array implementation of the List interface.ArrayList also comes with number of useful builtin functions such as
Size()
isEmpty()
contains()
clone()
and others. On top of these you can always convert your ArrayList to simple array using ArrayList function toArray(). Hope this answers your question. I'll prepare some code and share with you to further explain things you can achieve using List interface.

Use not native [] arrays but any kind of java collections
List<String> fileContent = Files.readAllLines(Paths.get(fileName));
fileContent.stream().forEach(System.out::println);
long amount = fileContent.stream()
.flatMap(line -> Arrays.stream(line.split(" +")))
.filter(word -> word.equalsIgnoreCase(userInput))
.count();
List<String> words = fileContent.stream()
.flatMap(line -> Arrays.stream(line.split(" +")))
.filter(word -> word.length() > 0)
.map(word -> word.equalsIgnoreCase(userInput) ? userInput2 : word)
.collect(Collectors.toList());
Files.write(Paths.get(fileName), String.join(" ", words).getBytes());
of course you can works with such lists more traditionally, with loops
for(String line: fileContent) {
...
}
or even
for (int i = 0; i < fileContent.size(); ++i) {
String line = fileContent.get(i);
...
}
i just like streams :)

Related

Reading a text file from implementation

I am trying to create an implementation that reads a file that the user has typed and submitted. The code for that is located in the SetTester class (shown below). In my implementation I already have an array declared called String[] myArray = new String [] {}; to hold the data from the file. How would I be able to take the file that is being called in the tester class and put it into that array?
public class SetTester
{
public static void main(String [] args) {
StringSet words = new MyStringSet();
Scanner file = null;
FileInputStream fs = null;
String input;
Scanner kb = new Scanner(System.in);
int wordCt = 0;
boolean ok = false;
while (!ok)
{
System.out.print("Enter name of input file: ");
input = kb.nextLine();
try
{
fs = new FileInputStream(input);
ok = true;
}
catch (FileNotFoundException e)
{
System.out.println(input + " is not a valid file. Try again.");
}
}
file = new Scanner(fs);
while (file.hasNext())
{
input = file.next();
words.insert(input);
System.out.println("Current capacity: " + words.getCapacity());
wordCt++;
}
System.out.println("There were " + wordCt + " words in the file");
System.out.println("There are " + words.inventory() + " elements in the set");
System.out.println("Enter a value to remove from the set: ");
input = kb.nextLine();
while (!words.contains(input))
{
System.out.println(input + " is not in the set");
System.out.println("Enter a value to remove from the set: ");
input = kb.nextLine();
}
words.remove(input);
System.out.println("There are now " + words.inventory() + " elements in the set");
System.out.println("The first 10 words in the set are: ");
for (int x=0; x<10; x++)
System.out.println(words.getFirstItem());
System.out.println("There are now " + words.inventory() + " elements in the set");
System.out.println("5 random words from the set are: ");
for (int x=0; x<5; x++)
System.out.println(words.getRandomItem());
System.out.println("There are now " + words.inventory() + " elements in the set");
}
}
For reading from a file I use this class:
import java.io.IOException;
import java.io.FileReader;
import java.io.BufferedReader;
public class ReadFile {
private static String path;
public ReadFile(String file_path){
path = file_path;
}
public String[] OpenFile() throws IOException {
FileReader fr = new FileReader(path);
BufferedReader textReader = new BufferedReader(fr);
int numberOfLines = readLines();
String[] textData = new String[numberOfLines];
for (int j = 0; j < numberOfLines; j++) {
textData[j] = textReader.readLine();
}
textReader.close();
return textData;
}
static int readLines() throws IOException {
FileReader file_to_read = new FileReader(path);
BufferedReader bf = new BufferedReader(file_to_read);
String aLine;
int numberOfLines = 0;
while((aLine = bf.readLine()) != null){
numberOfLines++;
}
bf.close();
return numberOfLines;
}
}
then in the class main you can add this code and you edit the path so you can read a file an get an array out of it
public static void main(String args[]) throws IOException {
ReadFile r = new ReadFile("here you put the path that the user provide");
String[] text = r.OpenFile();
ArrayList<String> array = new ArrayList<>();
array.addAll(Arrays.asList(text));
}
If you have any questions let me know!

Using formulas from a text/writing to a text

So, my lecture powerpoint slides and even my book is not really doing a good job (for my understanding that is) of explaining how to use formulas from a text document, then when the code runs/compiles successfully it will create a "Results.txt" in the same folder.
These are the formulas in a notepad doc. Nothing to crazy, just a proof of concept
4 * 5 ..
3 / 4...
3 - 1..
2 + 3..
import java.io.*;
import java.util.*;
public class ReadFileLineByLine {
public static void main(String[] args) throws FileNotFoundException {
String line;
int numberOfLines = 3;
String[] textData = new String[numberOfLines];
int i;
for(i = 0; i < numberOfLines; i++){
textData[i] = textReader.readLine();
}
text.Reader.close();
return textData;
try {
File inputfile = new File(args[0]); //new File("formulas.txt")
Scanner input = new Scanner(new File("C:\Users\Frost\Documents\Question4"));
BuffredReader br = new BufferedReader(new FileReader("C:\Users\Frost\Documents\Question4"));
PrintWriter output = new PrintWriter("Results.txt");
while (input.hasNextLine()) {
line = input.nextLine();
System.out.println("read <" + line + ">"); // Display message to commandline
// Declare ArrayList of for storing tokenized formula from String line
double result = 0; // The variable to store result of the operation
// Determine the operator and calculate value of the result
System.out.println(formula.get(0) + ' ' + formula.get(1) + ' ' +
formula.get(2) + " = " + result); // Display result to command line
// Write result to file
}
// Need to close input and output files
}
catch (FileNotFoundException e) {
System.out.println("Error reading file named " + Formulas.txt);
}
}
}
Here's something to get you started. The //TODO: comments are where you need to build your logic. Be sure to change the file paths back to what you need. I changed them to a Temp location. Also change the messages printed as I just put something there as proof of concept. I tried to comment thoroughly but don't hesitate to ask questions.
import java.io.*;
import java.util.*;
public class ReadFileLineByLine {
public static void main(String[] args) throws FileNotFoundException {
String line = "";
//Declare Scanner and PrintWriter outside of try clause so they can be closed in finally clause
Scanner input = null;
PrintWriter output = null;
try {
//Instantiate input and output file
input = new Scanner(new File("C:\\Temp\\test.txt"));
output = new PrintWriter(new File("C:\\Temp\\Results.txt"));
//Loop through lines in input file
while (input.hasNextLine()) {
line = input.nextLine();
// Display message to commandline
System.out.println("read <" + line + ">");
// Populate ArrayList of tokenized formula from String line
//TODO:
// The variable to store result of the operation
double result = 0;
// Determine the operator and calculate value of the result
//TODO:
// Write result to file
output.println("Print result of " + line + " to Results.txt");
}
} catch (FileNotFoundException e) {
//Exception thrown, print message to console
System.out.println("File Not Found: " + e.getMessage());
} finally {
//close files in finally clause so it happens even if exception is thrown
//I also set to null as extra precaution
input.close();
input = null;
output.close();
output = null;
}
}
}

InputStream reading file and counting lines/words

I'm working on a project and I'm trying to count
1) The number of words.
2) The number of lines in a text file.
My problem is that I can't figure out how to detect when the file goes to the next line so I can increment lines correctly. Basically if next is not a space increment words and if next is a new line, increment lines. How would I do this? Thanks!
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNext()) {
if (f.next().equals("\n")) {
lines++;
} else if (!(f.next().equals(" "))) {
words++;
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Try this:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
lines++;
for (String token : line.split("\\s+")) {
if (!token.isEmpty()) {
words++;
}
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Do you have to use InputStream? (Yes) It is better to use a BufferedReader with an InputStreamReader passed in so you can read the file line by line and increment while doing so.
numLines = 0;
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null)
{
numLines++;
// process the line.
}
}
Then to count the words just split the string using a regular expression that finds whitespaces. myStringArray = MyString.Split(MyRegexPattern); will then return a String[] of all the words. Then all you do is numWords += myStringArray.length();
You can use an InputStreamReader to create a bufferedreader which can read a file line by line:
int amountOfLines = 0;
try {BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))} catch (Exception e) {e.printStackTrace();}
String line;
while ((line = br.readLine()) != null{
numLines++;
// process the line.
}
You can then use the split(String) method to separate every part
Try following:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
String[] arr = line.split("\\s");
words += arr.length;
lines++;
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}

How to add line numbers to a text file?

So I need to make a program that reads a file containing text and then adds line numbers to each line. What I have so far prints out the line number but instead of just printing out each line, it prints all of the text in each line. How can I just have it so it prints out the line?
Here's the code I have so far:
public static void main(String[] args) throws FileNotFoundException {
try {
ArrayList<String> poem = readPoem("src\\P7_2\\input.txt");
number("output.txt",poem);
}catch(Exception e){
System.out.println("File not found.");
}
}
public static ArrayList<String> readPoem(String filename) throws FileNotFoundException {
ArrayList<String> lineList = new ArrayList<String>();
Scanner in = new Scanner(new File(filename));
while (in.hasNextLine()) {
lineList.add(in.nextLine());
}
in.close();
return lineList;
}
public static void number (String filename,ArrayList<String> lines) throws FileNotFoundException{
PrintWriter out = new PrintWriter(filename);
for(int i = 0; i<lines.size(); i++){
out.println("/* " + i + "*/" + lines);
}
out.close();
}
Here is a shorter version of your program using new capabilities offered by Java 7; it supposes that you have a short enough source file:
final Charset charset = StandardCharsets.UTF_8;
final String lineSeparator = System.lineSeparator();
final Path src = Paths.get("src\\P7_2\\input.txt");
final Path dst = Paths.get("output.txt");
try (
final BufferedWriter writer = Files.newBufferedWriter(src, charset, StandardOpenOption.CREATE);
) {
int lineNumber = 1;
for (final String line: Files.readAllLines(src, charset))
writer.write(String.format("/* %d */ %s%s", lineNumber++, line, lineSeparator));
writer.flush();
}
Use
out.println("/* " + i + "*/" + lines.get(i));
in place of
out.println("/* " + i + "*/" + lines);
You are printing complete list in each line.
i'd say this is your problem:
out.println("/* " + i + "*/" + lines);
//this prints all the lines each loop execution
you can try using:
int i = 1; //or the first value you wish
for(String a : lines){
out.println("/* " + i + "*/" + a);
i++;
}

Java Reading 2D array in from file, numbers separated by comma

This is some code that I found to help with reading in a 2D Array, but the problem I am having is this will only work when reading a list of number structured like:
73
56
30
75
80
ect..
What I want is to be able to read multiple lines that are structured like this:
1,0,1,1,0,1,0,1,0,1
1,0,0,1,0,0,0,1,0,1
1,1,0,1,0,1,0,1,1,1
I just want to essentially import each line as an array, while structuring them like an array in the text file.
Everything I have read says to use scan.usedelimiter(","); but everywhere I try to use it the program throws straight to the catch that replies "Error converting number". If anyone can help I would greatly appreciate it. I also saw some information about using split for the buffered reader, but I don't know which would be better to use/why/how.
String filename = "res/test.txt"; // Finds the file you want to test.
try{
FileReader ConnectionToFile = new FileReader(filename);
BufferedReader read = new BufferedReader(ConnectionToFile);
Scanner scan = new Scanner(read);
int[][] Spaces = new int[10][10];
int counter = 0;
try{
while(scan.hasNext() && counter < 10)
{
for(int i = 0; i < 10; i++)
{
counter = counter + 1;
for(int m = 0; m < 10; m++)
{
Spaces[i][m] = scan.nextInt();
}
}
}
for(int i = 0; i < 10; i++)
{
//Prints out Arrays to the Console, (not needed in final)
System.out.println("Array" + (i + 1) + " is: " + Spaces[i][0] + ", " + Spaces[i][1] + ", " + Spaces[i][2] + ", " + Spaces[i][3] + ", " + Spaces[i][4] + ", " + Spaces[i][5] + ", " + Spaces[i][6]+ ", " + Spaces[i][7]+ ", " + Spaces[i][8]+ ", " + Spaces[i][9]);
}
}
catch(InputMismatchException e)
{
System.out.println("Error converting number");
}
scan.close();
read.close();
}
catch (IOException e)
{
System.out.println("IO-Error open/close of file" + filename);
}
}
I provide my code here.
public static int[][] readArray(String path) throws IOException {
//1,0,1,1,0,1,0,1,0,1
int[][] result = new int[3][10];
BufferedReader reader = new BufferedReader(new FileReader(path));
String line = null;
Scanner scanner = null;
line = reader.readLine();
if(line == null) {
return result;
}
String pattern = createPattern(line);
int lineNumber = 0;
MatchResult temp = null;
while(line != null) {
scanner = new Scanner(line);
scanner.findInLine(pattern);
temp = scanner.match();
int count = temp.groupCount();
for(int i=1;i<=count;i++) {
result[lineNumber][i-1] = Integer.parseInt(temp.group(i));
}
lineNumber++;
scanner.close();
line = reader.readLine();
}
return result;
}
public static String createPattern(String line) {
char[] chars = line.toCharArray();
StringBuilder pattern = new StringBuilder();;
for(char c : chars) {
if(',' == c) {
pattern.append(',');
} else {
pattern.append("(\\d+)");
}
}
return pattern.toString();
}
The following piece of code snippet might be helpful. The basic idea is to read each line and parse out CSV. Please be advised that CSV parsing is generally hard and mostly requires specialized library (such as CSVReader). However, the issue in hand is relatively straightforward.
try {
String line = "";
int rowNumber = 0;
while(scan.hasNextLine()) {
line = scan.nextLine();
String[] elements = line.split(',');
int elementCount = 0;
for(String element : elements) {
int elementValue = Integer.parseInt(element);
spaces[rowNumber][elementCount] = elementValue;
elementCount++;
}
rowNumber++;
}
} // you know what goes afterwards
Since it is a file which is read line by line, read each line using a delimiter ",".
So Here you just create a new scanner object passing each line using delimter ","
Code looks like this, in first for loop
for(int i = 0; i < 10; i++)
{
Scanner newScan=new Scanner(scan.nextLine()).useDelimiter(",");
counter = counter + 1;
for(int m = 0; m < 10; m++)
{
Spaces[i][m] = newScan.nextInt();
}
}
Use the useDelimiter method in Scanner to set the delimiter to "," instead of the default space character.
As per the sample input given, if the next row in a 2D array begins in a new line, instead of using a ",", multiple delimiters have to be specified.
Example:
scan.useDelimiter(",|\\r\\n");
This sets the delimiter to both "," and carriage return + new line characters.
Why use a scanner for a file? You already have a BufferedReader:
FileReader fileReader = new FileReader(filename);
BufferedReader reader = new BufferedReader(fileReader);
Now you can read the file line by line. The tricky bit is you want an array of int
int[][] spaces = new int[10][10];
String line = null;
int row = 0;
while ((line = reader.readLine()) != null)
{
String[] array = line.split(",");
for (int i = 0; i < array.length; i++)
{
spaces[row][i] = Integer.parseInt(array[i]);
}
row++;
}
The other approach is using a Scanner for the individual lines:
while ((line = reader.readLine()) != null)
{
Scanner s = new Scanner(line).useDelimiter(',');
int col = 0;
while (s.hasNextInt())
{
spaces[row][col] = s.nextInt();
col++;
}
row++;
}
The other thing worth noting is that you're using an int[10][10]; this requires you to know the length of the file in advance. A List<int[]> would remove this requirement.

Categories