Resetting Java while loop - java

I currently have 2 loops, one which gets a timestamp, and another while loop to find the mapped information based off that time stamp and output in a certain way.
Issue I have is I am currently looping through a text, and want it to start reading the file from the beginning again when the isdone="N" for the second loop, however, this does not seem to be the case.
Code so far:
public static void organiseFile() throws FileNotFoundException {
String directory = "C:\\Users\\xxx\\Desktop\\Files\\ex1";
Scanner fileIn = new Scanner(new File(directory + "_temp.txt"));
Scanner readIn = new Scanner(new File(directory + ".txt"));
PrintWriter out = new PrintWriter(directory + "_ordered.txt");
ArrayList<String> lines = new ArrayList<String>();
String readTimeStamp = "";
String timeStampMapping = "";
String outputFirst = "";
String outputSecond = "";
String outputThird = "";
String previousTimeStamp = "";
String doneList = "";
String isdone = "";
int counter = 1;
// Loop to get time stamps
while(fileIn.hasNextLine()) {
readTimeStamp = fileIn.nextLine();
if(readTimeStamp != null && readTimeStamp.trim().length() > 0) {
readTimeStamp = readTimeStamp.substring(12, 25);
System.out.println(readTimeStamp);
// Previous time stamp found, no need to loop through it again
if(doneList.contains(readTimeStamp))
isdone = "Y";
// Counter in place to stop outputting the first record, otherwise output file and clear variables down
else if(!previousTimeStamp.equals(readTimeStamp) && counter > 1) {
out.println(outputFirst + outputSecond + outputThird);
System.out.println("Outputting....");
outputFirst = "";
outputSecond = "";
outputThird = "";
counter = 1;
}
// New time stamp found, start finding values in second loop
else
isdone = "N";
// Secondary loop to find match of record
while(readIn.hasNextLine() && isdone.equals("N")) {
System.out.println("Mapping...");
timeStampMapping = readIn.nextLine();
System.out.println(timeStampMapping);
// When a record has been found with matching time stamps, start ordering
if(timeStampMapping.contains(readTimeStamp)) {
previousTimeStamp = readTimeStamp;
System.out.println(previousTimeStamp);
if(timeStampMapping.contains("[EVENT=agentStateEvent]")) {
outputFirst += timeStampMapping + "\r\n";
} else if(timeStampMapping.contains("[EVENT=TerminalConnectionCreated]")) {
outputSecond += timeStampMapping + "\r\n";
} else {
outputThird += timeStampMapping + "\r\n";
doneList += readTimeStamp + ",";
}
counter++;
}
}
}
}
System.out.println("Outputting final record");
out.println(outputFirst + outputSecond + outputThird);
System.out.println("Complete!");
out.close();
}

You can use Scanner.reset() to reset it to the beginning of the file. For example, after your second while-loop include:
if (isdone.equals("Y")) {
fileIn.reset();
}
Btw: why are you using String for isdone instead of boolean??

Related

When I run my code I get (0, null) and cant figure out why

I am creating a program that is reading a file of names and ages then printing them out in ascending order. I am parsing through the file to figure out the number of name age pairs and then making my array that big.
The input file looks like this:
(23, Matt)(2000, jack)(50, Sal)(47, Mark)(23, Will)(83200, Andrew)(23, Lee)(47, Andy)(47, Sam)(150, Dayton)
When I am running my code I get the output of (0,null) and I am not sure why. I have been trying to fix it for a while and am lost. If anyone can help that would be great My code is below.
public class ponySort {
public static void main(String[] args) throws FileNotFoundException {
int count = 0;
int fileSize = 0;
int[] ages;
String [] names;
String filename = "";
Scanner inputFile = new Scanner(System.in);
File file;
do {
System.out.println("File to read from:");
filename = inputFile.nextLine();
file = new File(filename);
//inputFile = new Scanner(file);
}
while (!file.exists());
inputFile = new Scanner(file);
if (!inputFile.hasNextLine()) {
System.out.println("No one is going to the Friendship is magic Party in Equestria.");
}
while (inputFile.hasNextLine()) {
String data1 = inputFile.nextLine();
String[] parts1 = data1.split("(?<=\\))(?=\\()");
for (String part : parts1) {
String input1 = part.replaceAll("[()]", "");
Integer.parseInt(input1.split(", ")[0]);
fileSize++;
}
}
ages = new int[fileSize];
names = new String[fileSize];
while (inputFile.hasNextLine()) {
String data = inputFile.nextLine();
String[] parts = data.split("(?<=\\))(?=\\()");
for (String part : parts) {
String input = part.replaceAll("[()]", "");
ages[count] = Integer.parseInt(input.split(", ")[0]);
names[count] = input.split(", ")[1];
count++;
}
}
ponySort max = new ponySort();
max.bubbleSort(ages, names, count);
max.printArray(ages, names, count);
}
public void printArray(int ages[], String names[], int count) {
System.out.print("(" + ages[0] + "," + names[0] + ")");
// Checking for duplicates in ages. if it is the same ages as one that already was put in them it wont print.
for (int i = 1; i < count; i++) {
if (ages[i] != ages[i - 1]) {
System.out.print("(" + ages[i] + "," + names[i] + ")");
}
}
}
public void bubbleSort(int ages[], String names[], int count ){
for (int i = 0; i < count - 1; i++) {
for (int j = 0; j < count - i - 1; j++) {
// age is greater so swaps age
if (ages[j] > ages[j + 1]) {
// swap the ages
int temp = ages[j];
ages[j] = ages[j + 1];
ages[j + 1] = temp;
// must also swap the names
String tempName = names[j];
names[j] = names[j + 1];
names[j + 1] = tempName;
}
}
}
}
}
output example
File to read from:
file.txt
(0,null)
Process finished with exit code 0
What your code does is to Scan the file twice.
In the first loop you do
String data1 = inputFile.nextLine();
Code reads first line and then scanner goes to the next (second) line.
Later you do again inputFile.nextLine(); The second line is empty and the code never goes into the second loop and content is never read.
If you can use Lists, you should create two array lists and add ages and names into the arraylists in the first scan, so you scan the file once. When done, you could get the Array out of the arraylist.
If you should only use arrays and you want a simple update, just add another Scanner before the second loop:
ages = new int[fileSize];
names = new String[fileSize];
inputFile = new Scanner(file); // add this line

Merging two files line by line Java

Is there a more efficient way than i'm currently using, to merge two files line by line appending the line from file2 onto file1?
If file1 contains
a1
b1
c1
And file2 contains
a2
b2
c2
Then the output file should contain
a1,a2
b1,b2
c1,c2
The current combineRecords method looks like
private FileSheet combineRecords(ArrayList<FileSheet> toCombine) throws IOException
{
ArrayList<String> filepaths = new ArrayList<String>();
for (FileSheet sheetIterator : toCombine)
{
filepaths.add(sheetIterator.filepath);
}
String filepathAddition = "";
for (String s : filepaths)
{
filepathAddition = filepathAddition + s.split(".select.")[1].replace(".csv", "") + ".";
}
String outputFilepath = subsheetDirectory + fileHandle.getName().split(".csv")[0] + ".select." + filepathAddition + "csv";
Log.log("Output filepath " + outputFilepath);
long mainFileLength = toCombine.get(0).recordCount();
for (FileSheet f : toCombine)
{
int ordinal = toCombine.indexOf(f);
if (toCombine.get(ordinal).recordCount() != mainFileLength)
{
Log.log("Error : Record counts for 0 + " + ordinal);
return null;
}
}
FileSheet finalValues;
Log.log("Starting iteration streams");
BufferedWriter out = new BufferedWriter(new FileWriter(outputFilepath, false));
List<BufferedReader> streams = new ArrayList<>();
for (FileSheet j : toCombine)
{
streams.add(new BufferedReader(new FileReader(j.filepath)));
}
String finalWrite = "";
for (int i = 0; i < toCombine.get(0).recordCount(); i++)
{
for (FileSheet j : toCombine)
{
int ordinal = toCombine.indexOf(j);
finalWrite = finalWrite + streams.get(ordinal).readLine();
if (toCombine.indexOf(j) != toCombine.size() - 1)
{
finalWrite = finalWrite + ",";
}
else
{
finalWrite = finalWrite + "\n";
}
}
if (i % 1000 == 0 || i == toCombine.get(0).recordCount() - 1)
{
// out.write(finalWrite + "\n");
Files.write(Paths.get(outputFilepath),(finalWrite).getBytes(),StandardOpenOption.APPEND);
finalWrite = "";
}
}
out.close();
Log.log("Finished combineRecords");
finalValues = new FileSheet(outputFilepath,0);
return finalValues;
}
I've tried both bufferedwriters and files.write, and they have similar times to create file3, both in the 1:30 minute range, but i'm not sure if the bottleneck is at reading or writing
The sample files i'm using are currently at 36,000 records, but the actual file i'll be using is ~650,000 so taking (if it scales linearly) 1625 seconds is completely unfeasible for this operation
Edit : I've modified the code to only open files once, rather than per iteration, however i'm now getting stream closed when skipping to the nth line
I thought that by doing streams.get(ordinal).skip(i).findFirst().get(); would return a new stream instead of skipping then closing the stream
Edit 2 : Modified the code to use bufferedreaders instead of streams, and write to file every 1000 lines read, and thats determined that the bottleneck is reading, because it still takes ~1:30 to do
First of all concating string using + operator is ok when it is not under loop. But when you want to merge strings in a loop you should use StringBuilder for better performance.
Second thing which you can improve you can write to file at the end like:
StringBuilder finalWrite = new StringBuilder();
for (int i = 0; i < toCombine.get(0).recordCount(); i++)
{
for (FileSheet j : toCombine)
{
int ordinal = toCombine.indexOf(j);
finalWrite.append(streams.get(ordinal).readLine());
if (toCombine.indexOf(j) != toCombine.size() - 1)
{
finalWrite.append(",");
}
else
{
finalWrite.append("\n");
}
}
}
Files.write(Paths.get(outputFilepath), finalWrite.toString().getBytes());

Reading & Breaking CSV File in Java:

I am editing this question to be more specific and I've learned some Jave to find the solution to my problem. I have a file in CSV format like this:
or in excel like this:
Now I am using Java program to read the second line of file and separate each Comma Separated Value and write it to console as well as on other output file and it was done easily. Now I'm trying to break the last value of:
S/1,M/1,L/1,XL/1 | 2XL/1,3XL/1,4XL/1,5XL/1 | MT/1,LT/1 (Original)
S/1,M/1,L/1,XL/1,2XL/1,3XL/1,4XL/1,5XL/1,MT/1,LT/1 (Modified using program to remove spaces and replacing the Pipes (|) with comma.
In each value, There is the size name before Forward Slash (/) and its quantity is after that. What I'm trying is using the Forward Slash (/) to separate the size with its quantity. And the problem is that the size may contain the forward slash as well (e.g. 12/BT or 2BT/2x). I've tried many algorithms like reversing the whole array or storing the slash count but not getting the success. The whole code to read file and break the comma separated values into separate columns of file is as following:
import java.io.*;
import javax.swing.*;
public class ReadFile3c{
public static void main(String args[]){
try{
//Getting File Name
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
//Creating Stream with File
FileReader fr = new FileReader(fileName);
//Applying Buffer Filter
BufferedReader br = new BufferedReader(fr);
//Reading First line then Second Line
String s = br.readLine();
s = br.readLine();
s = s + ",";//adding comma at the end of the file
s = s.replaceAll("\\s",""); //Eliminating Spaces
s = s.replaceAll("\\|",","); //Replacing Pipes with comma
char charArray[] = s.toCharArray();
//Declaring Strings and variablse for value separating function
int n = 0; //Array Variable
int m = 0; //Array Variable
String[] inverted = new String[3]; //String to store inverted Commas Values
String[] comma = new String[10]; //String to store comma Values
String value = ""; //Storing character values
try{
//Loop to cycle each character of file
for(int j = 0; j<charArray.length;j++){
//Inverted comma value separator
if (charArray[j] == '"') {
j++;
//loop to gather values b/w invreted comma
while((charArray[j] != '"')){
value = value + charArray[j];
j++;
}
inverted[n] = value;
n++;
j++;
value = "";
}else{
j = j - 1;
//comma Value separator
if (charArray[j] == ','){
j++;
//loop to gether values b/w commas
while((charArray[j] !=',')){
value = value + charArray[j];
j++;
}
comma[m] = value;
m++;
value = "";
}
}
}
}catch(Exception ex){
System.out.println("in inner Exception Block" + ex);
}
//declaring variables to storing values
String name, patternCode, placeSizeQty,width,length,utill,pArea,pPerimeter,totalPcs,placePcs,tSizes;
name = inverted[0];
patternCode = inverted[1];
placeSizeQty = inverted[2];
width = comma[0];
length = comma[1];
utill = comma[2];
pArea = comma[3];
pPerimeter = comma[4];
totalPcs = comma[5];
placePcs = comma[6];
tSizes = comma[7];
//printing all values on Console
System.out.println("\nMarkerName: " + name);
System.out.println("Width :" + width);
System.out.println("Length :" + length);
System.out.println("Utill :" + utill);
System.out.println("Place Area :" + pArea);
System.out.println("Place Perimeter :" + pPerimeter);
System.out.println("PatternCode: " + patternCode);
System.out.println("PlaceSizeQty: " + placeSizeQty);
System.out.println("Total Pcs :" + totalPcs);
System.out.println("Place Pcs :" + placePcs);
System.out.println("Total Sizes :" + tSizes);
//Creating Output file
String fileOutput = JOptionPane.showInputDialog("Enter Output File Name") + ".txt";
//File Writer
try{
//Creating Stream with output file
FileWriter fw = new FileWriter(fileOutput);
//Applying Buffring Stream
PrintWriter pw = new PrintWriter(fw);
//Declaration
String outputLine = null;
//Writing Inverted inputs
for (int u = 0; u <=2 ;u++ ) {
outputLine = inverted[u];
pw.println(outputLine);
System.out.println("Writing: " + outputLine);
}//end of for
//writing comma inputs
for (int t = 0;t <=7 ; t++ ) {
outputLine = comma[t];
pw.println(outputLine);
System.out.println("Writing: " + outputLine);
}//end of for
pw.flush();
pw.close();
fw.close();
fr.close();
br.close();
}catch(Exception ex){
System.out.println("Output: " + ex);
}//End of output catch
}catch(IOException ex){
System.out.println(ex);
}//end of catch
}//end of catch
}//end of Class
And the code to Break the Size and quantity and store it in Double array (Not completed) is as Following:
import java.io.*;
import javax.swing.*;
public class ReadFileInvert{
public static void main(String args[]){
try{
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
System.out.println(s);
s = s.replaceAll("\\s","");
s = s.replaceAll("\\|",",");
System.out.println(s);
char charArray[] = s.toCharArray();
char charArrayI[] = new char[charArray.length + 1];
int j = 0;
String value = "";
for(int i = charArray.length; i > 0; i--){
charArrayI[j] = charArray[i];
value = value + charArrayI[j];
j++;
}
System.out.println("1" + value);
}catch(Exception ex){
System.out.println(ex);
}
}
}
Now in simple I just want to Separate the sizes (Which may contains the Forward Slashes) with its quantity (After last slash of each value) and store it in double array Like charArray[sizeName][Qty]. Sorry if i didn't explained my problem well as I'm Learning the Coding. but I'll provide as much info as you want.
Have you considered looking at the CAD software export to see if there is a solution on the file creation side? Or is this file coming from a third party?
OK. So, after the hard work of whole day, I've found the following solution to my problem:
import java.io.*;
import javax.swing.*;
public class ReadFileInvert2{
public static void main(String args[]){
try{
String fileName = JOptionPane.showInputDialog("Enter File Name") + ".csv";
FileReader fr = new FileReader(fileName);
BufferedReader br = new BufferedReader(fr);
String s = br.readLine();
System.out.println(s);
s = s.replaceAll("\\s","");
s = s.replaceAll("\\|",",");
System.out.println(s);
char charArray[] = s.toCharArray();
int x = charArray.length - 1;
charArray[x] = ',';
int no = 1;
int size = 1;
int qty = 2;
String sizeS = "";
String qtyS = "";
//String resSet[][] = new String[4][2];
String resSize[] = new String[20];
String resQty[] = new String[20];
int slashNo = 0;
String value = "";
for (int j = 1; j < charArray.length; j++){
int n = j;
if (charArray[j] == ','){
j++;
}
while (charArray[j] != ','){
if (charArray[j] == '/') {
slashNo = j;
//j++;
}
value = value + charArray[j];
//System.out.println(value);
j++;
}
for (int k = n;k < slashNo; k++ ) {
sizeS = sizeS + charArray[k];
//System.out.println(sizeS);
}
for (int l = slashNo + 1; l < j; l++ ) {
qtyS = qtyS + charArray[l];
//System.out.println(qtyS);
}
resSize[no] = sizeS;
System.out.println(resSize[no]);
resQty[no] = qtyS;
System.out.println(resQty[no]);
System.out.println("Size is: " + resSize[no] + ", and Qty is: " + resQty[no]);
no++;
slashNo = 0;
sizeS = "";
qtyS = "";
}
String fileOutput = JOptionPane.showInputDialog("Enter Output File Name: ") + ".txt";
try{
FileWriter fw = new FileWriter(fileOutput);
PrintWriter pw = new PrintWriter(fw);
String outputSize = null;
String outputQty = null;
for (int t = 1; t < no; t++) {
outputSize = resSize[t];
outputQty = resQty[t];
pw.println(outputSize + " = " + outputQty);
System.out.println("Writing: "+ outputSize + " = " + outputQty);
}
pw.flush();
pw.close();
fw.close();
fr.close();
br.close();
}catch(Exception ex){
System.out.println("Output " + ex);
}
}catch(Exception ex){
System.out.println(ex);
}
}
}
Now its in Generic form but will improve it later. But still its working fine. Thanks for your Help stack overflow Community.

My array Printing NULL

In the method, i have all these initialize
Scanner input = new Scanner(System.in);
File file = new File("order.dat");
File viewOrder = new File("ViewOrder.dat");
String orderNo, itemNo, itemNameHolder, qtyHolder, priceHolder, status;
int hold, count = 0, countArray = 0;
double tempPriceHolder, totalPrice = 0;
String tempStatus = "";
String[] holdItemNo = null;
String[] holdName = null;
Integer[] holdQty = null;
Double[] holdTotal = null;
String[] holdStatus = null;
After, i try to read all my content in the file and store the content into holdX array
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while ((line = br.readLine()) != null) {
String tokens[] = line.split(";");
orderNo = tokens[0];
itemNo = tokens[1];
itemNameHolder = tokens[2];
qtyHolder = tokens[3];
priceHolder = tokens[4];
status = tokens[5];
if (orderNo.equalsIgnoreCase(userOrderNo)) {
tempPriceHolder = Double.parseDouble(priceHolder);
hold = Integer.parseInt(qtyHolder);
tempPriceHolder = tempPriceHolder * hold;
totalPrice += tempPriceHolder;
countArray++;
holdItemNo = new String[countArray];
holdName = new String[countArray];
holdQty = new Integer[countArray];
holdTotal = new Double[countArray];
holdStatus = new String[countArray];
if (status.matches("s")) {
tempStatus = "Success";
} else if (status.matches("p")) {
tempStatus = "Partially Full";
} else if (status.matches("o")) {
tempStatus = "Out of Stock";
}
holdItemNo[count] = itemNo;
holdName[count] = itemNameHolder;
holdQty[count] = hold;
holdTotal[count] = tempPriceHolder;
holdStatus[count] = tempStatus;
count++;
}
}
} catch (Exception e) {
System.out.println("Error");
}
Final, i write all my array into a new file.
System.out.printf("%s %15s %15s %10s %10s\n", "Item No", "Description", "Quantity", "Total", "Status");
for (int i = 0; i < holdItemNo.length; i++) {
System.out.printf("\n%-11s %-18s %-13s $%-8s %s \n", holdItemNo[i], holdName[i], holdQty[i], holdTotal[i], holdStatus[i]);
}
System.out.println("-----------------------------------------------------------------------");
System.out.printf("%46s %s\n", "$", totalPrice);
System.out.print("Print Order to file Y/N: ");
String choice = input.next();
if (choice.equalsIgnoreCase("y")) {
try {
PrintWriter bw = new PrintWriter(new FileWriter("ViewOrder.dat", true));
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
bw.flush();
bw.close();
System.out.println("Sucessfull!");
} catch (Exception e) {
System.out.println("Error");
}
} else if (choice.equalsIgnoreCase("n")) {
System.out.println("");
}
but the problem is even my code is working but the output is not what i expected. It printed out the printed out the last content and also the sub price is working as well but the rest is only printed out NULL.
Example
Also, it gave me warning of Derefencing possible null pointer on the array.length
for (int i = 0; i < holdItemNo.length; i++) {
bw.write(userOrderNo + ";" + holdItemNo[i] + ";" + holdName[i] + ";" + holdQty[i] + ";" + holdTotal[i] + ";" + holdStatus[i] + "\n");
bw.flush();
}
Guessing:
holdItemNo = new String[countArray];
and the following lines: you are creating these new array objects within your reading loop (inside a condition).
So probably that condition never goes true; therefore your arrays stay all null. But even when the condition is met - you probably expect that to happen more then once. And guess what: you are creating completely new arrays then. While throwing away the previously created array. Each time the if condition turns true you will lose previously stored values!
So the answer is: create your arrays before entering the loop. This means that you either have to query "how many slots to create" upfront; or you have to create an array with say 100 empty slots; and within your loop you then have to check if you still have free slots.
Or you start using java.util.List resp. ArrayList - which allows for dynamic adding of elements.

Java program to count lines, words, and chars from a text given file

I am practicing to write a program that gets a text file from user and provides data such as characters, words, and lines in the text.
I have searched and looked over the same topic but cannot find a way to make my code run.
public class Document{
private Scanner sc;
// Sets users input to a file name
public Document(String documentName) throws FileNotFoundException {
File inputFile = new File(documentName);
try {
sc = new Scanner(inputFile);
} catch (IOException exception) {
System.out.println("File does not exists");
}
}
public int getChar() {
int Char= 0;
while (sc.hasNextLine()) {
String line = sc.nextLine();
Char += line.length() + 1;
}
return Char;
}
// Gets the number of words in a text
public int getWords() {
int Words = 0;
while (sc.hasNext()) {
String line = sc.next();
Words += new StringTokenizer(line, " ,").countTokens();
}
return Words;
}
public int getLines() {
int Lines= 0;
while (sc.hasNextLine()) {
Lines++;
}
return Lines;
}
}
Main method:
public class Main {
public static void main(String[] args) throws FileNotFoundException {
DocStats doc = new DocStats("someText.txt");
// outputs 1451, should be 1450
System.out.println("Number of characters: "
+ doc.getChar());
// outputs 0, should be 257
System.out.println("Number of words: " + doc.getWords());
// outputs 0, should be 49
System.out.println("Number of lines: " + doc.getLines());
}
}
I know exactly why I get 1451 instead of 1451. The reason is because I do not have '\n' at the end of the last sentence but my method adds
numChars += line.length() + 1;
However, I cannot find a solution to why I get 0 for words and lines.
*My texts includes elements as: ? , - '
After all, could anyone help me to make this work?
**So far, I the problem that concerns me is how I can get a number of characters, if the last sentence does not have '\n' element. Is there a chance I could fix that with an if statement?
-Thank you!
After doc.getChar() you have reached the end of file. So there's nothing more to read in this file!
You should reset your scanner in your getChar/Words/Lines methods, such as:
public int getChar() {
sc = new Scanner(inputFile);
...
// solving your problem with the last '\n'
while (sc.hasNextLine()) {
String line = sc.nextLine();
if (sc.hasNextLine())
Char += line.length() + 1;
else
Char += line.length();
}
return char;
}
Please note that a line ending is not always \n! It might also be \r\n (especially under windows)!
public int getWords() {
sc = new Scanner(inputFile);
...
public int getLines() {
sc = new Scanner(inputFile);
...
I would use one sweep to calculate all 3, with different counters. just a loop over each char, check if its a new word etc, increase counts , use Charater.isWhiteSpace *
import java.io.*;
/**Cound lines, characters and words Assumes all non white space are words so even () is a word*/
public class ChrCounts{
String data;
int chrCnt;
int lineCnt;
int wordCnt;
public static void main(String args[]){
ChrCounts c = new ChrCounts();
try{
InputStream data = null;
if(args == null || args.length < 1){
data = new ByteArrayInputStream("quick brown foxes\n\r new toy\'s a fun game.\nblah blah.la la ga-ma".getBytes("utf-8"));
}else{
data = new BufferedInputStream( new FileInputStream(args[0]));
}
c.process(data);
c.print();
}catch(Exception e){
System.out.println("ee " + e);
e.printStackTrace();
}
}
public void print(){
System.out.println("line cnt " + lineCnt + "\nword cnt " + wordCnt + "\n chrs " + chrCnt);
}
public void process(InputStream data) throws Exception{
int chrCnt = 0;
int lineCnt = 0;
int wordCnt = 0;
boolean inWord = false;
boolean inNewline = false;
//char prev = ' ';
while(data.available() > 0){
int j = data.read();
if(j < 0)break;
chrCnt++;
final char c = (char)j;
//prev = c;
if(c == '\n' || c == '\r'){
chrCnt--;//some editors do not count line seperators as new lines
inWord = false;
if(!inNewline){
inNewline = true;
lineCnt++;
}else{
//chrCnt--;//some editors dont count adjaccent line seps as characters
}
}else{
inNewline = false;
if(Character.isWhitespace(c)){
inWord = false;
}else{
if(!inWord){
inWord = true;
wordCnt++;
}
}
}
}
//we had some data and last char was not in new line, count last line
if(chrCnt > 0 && !inNewline){
lineCnt++;
}
this.chrCnt = chrCnt;
this.lineCnt = lineCnt;
this.wordCnt = wordCnt;
}
}

Categories