I am currently trying to compare the lines in a textfile to find the shortest line and longest line and display how many characters are in each. The code I have listed below allows me to count all the character, words, and lines. I have no idea where to start comparing the lines? Any help would be appreciated.
import java.util.Scanner;
import java.io.*;
public class Test{
public static void main(String [] args){
System.out.println("Please enter the filename: ");
Scanner input = new Scanner(System.in);
String fileName = input.nextLine();
FileReader fReader;
try {
fReader = new FileReader(fileName);
BufferedReader reader = new BufferedReader(fReader);
String cursor; //
String content = "";
int lines = 0;
int words = 0;
int chars = 0;
while((cursor = reader.readLine()) != null){
// count lines
lines += 1;
content += cursor;
// count words
String []_words = cursor.split(" ");
for( String w : _words)
{
words++;
}
}
chars = content.length();
System.out.println("The filename is " + fileName);
System.out.println(chars + " Characters,");
System.out.println(words + " words and " + lines + " lines.");
} catch (FileNotFoundException ex) {
// Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("File not found!");
} catch (IOException ex) {
//Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("An error has occured: " + ex.getMessage());
}
}
}
You must create 2 vars to store short and long lines...
String longest = "";
String shortest = "";
Then in your existing code, compare with current line:
while((cursor = reader.readLine()) != null){
// compare shortest and longest.
int currentSize = cursor.lenght;
if (currentSize > longest.lenght || longest.equals("")) {
longest = cursor;
} else if (currentSize < shortest.lenght || longest.equals("")) {
shortest = cursor;
}
// count lines
lines += 1;
content += cursor;
// count words
String []_words = cursor.split(" ");
for( String w : _words)
{
words++;
}
}
After the loop you can do what you need with results:
System.out.println("Longest line has " + longest.lenght);
System.out.println("Shortest line has " + shortest.lenght);
If you only need the sizes and not the lines you can create int variables.
int longest = 0;
int shortest = 0;
// then inside the loop
int currentSize = cursor.lenght;
if (currentSize > longest || currentSize = 0) {
longest = currentSize;
} else if (currentSize < shortest || currentSize = 0) {
shortest = currentSize;
}
You need 2 String variables, one to hold the shortest String and one to hold the longest String. Then as you process each line, compare the length of the current line to the shortest/longest.
If it is shorter than your shortest String, set the shortest String to the current line.
else
If it is longer than your longest String, set the longest String to the current line.
Process the results at the end on those two String variables.
Related
I want to print out the total number of letters (not including whitespace characters) of all the Latin names in the data file. Duplicate letters must be counted. This is what I have done so far:
List<Person> peopleFile = new ArrayList<>();
int numberOfLetters = 0;
try {
BufferedReader br = new BufferedReader(new FileReader("people_data.txt"));
String fileRead = br.readLine();
while (fileRead != null) {
String[] tokenSize = fileRead.split(":");
String commonName = tokenSize[0];
String latinName = tokenSize[1];
Person personObj = new Person(commonName, latinName);
peopleFile.add(personObj);
fileRead = br.readLine();
// Iterating each word
for (String s: tokenSize) {
// Updating the numberOfLetters
numberOfLetters += s.length();
}
}
br.close();
}
catch (FileNotFoundException e) {
System.out.println("file not found");
}
catch (IOException ex) {
System.out.println("An error has occured: " + ex.getMessage());
}
System.out.print("Total number of letters in all Latin names = ");
System.out.println(numberOfLetters);
The problem is that it prints out all number of letters in the file, I just want it to print out the number of characters in the Latin names.
The text file:
David Lee:Cephaloscyllium ventriosum
Max Steel:Galeocerdo cuvier
Jimmy Park:Sphyrna mokarren
What you are doing wrong is you are counting all the names despite you tokenize them. You can use this method to count letters of any String or Sentence.
public static int countLetter(String name) {
int count = 0;
if(name != null && !name.isEmpty()) {
/* This regular expression is splitting String at the
* sequence of Non-alphabetic characters. Hence actually
* splitting the Name into group of words */
String[] tokens = name.split("[^a-zA-Z]+");
for(String token : tokens) {
count += token.length();
}
}
return count;
}
And replace these lines
/* Note: here you are iterating all your Names from each line */
for (String s: tokenSize) {
// Updating the numberOfLetters
numberOfLetters += s.length();
}
with this
numberOfLetters += countLetter(latinName);
Does it make sense ? I hope you found your problem.
NB: you can experiment with this regex here
Get rid of all the blank spaces before summing the length :
s=s.replaceAll("[ \n\t]+","");
numberOfLetters += s.length();
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.
Good day!
I have created a code using Netbeans and it executes the processes just fine.
Now, i want my input to given and output to be displayed through a user interface. I have then created a 2 Jframes, 1 to collect the user's input and the other to display the results after execution by the code.
But, i am unable to link the interface to the main class(called NgramBetaE) as i am not aware of how i can do so.
I highly welcome suggestions.
The main class in its entirety is;
package ngrambetae;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
/**
*
* #author 201102144
*/
public class NgramBetaE {
static LinkedList<String> allWords = new LinkedList<String>();
static LinkedList<String> distinctWords = new LinkedList<String>();
static String[] hashmapWord = null;
static int wordCount;
public static HashMap<String,HashMap<String, Integer>> hashmap = new HashMap<>();
public static HashMap<String,HashMap<String, Integer>> bigramMap = new HashMap<>();
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
//prompt user input
Scanner input = new Scanner(System.in);
//read words from collected corpus; a number of .txt files
File directory = new File("Corpus");
File[] listOfFiles = directory.listFiles();//To read from all listed iles in the "directory"
int lineNumber = 0;
String line;
String files;
String delimiters = "[()?!:;,.\\s]+";
//reading from a list of text files
for (File file : listOfFiles) {
if (file.isFile()) {
files = file.getName();
try {
if (files.endsWith(".txt") || files.endsWith(".TXT")) { //ensures a file being read is a text file
BufferedReader br = new BufferedReader(new FileReader(file));
while ((line = br.readLine()) != null) {
line = line.toLowerCase();
hashmapWord = line.split(delimiters);
//CALCULATING UNIGRAMS
for(int s = 0; s < hashmapWord.length; s++){
String read = hashmapWord[s];
allWords.add(read);
//count the total number of words in all the text files combined
//TEST
wordCount = 0;
for (int i = 0; i < allWords.size(); i++){
wordCount ++;
}
}
//CALCULATING BIGRAM FREQUENCIES
for(int s = 0; s < hashmapWord.length -1; s++){
String read = hashmapWord[s];
final String read1 = hashmapWord[s + 1];
HashMap<String, Integer> counter = bigramMap.get(read);
if (null == counter) {
counter = new HashMap<String, Integer>();
bigramMap.put(read, counter);
}
Integer count = counter.get(read1);
counter.put(read1, count == null ? 1 : count + 1);
}
//CALCULATING TRIGRAM FREQUENCIES
for(int s = 0; s < hashmapWord.length - 2; s++){
String read = hashmapWord[s];
String read1 = hashmapWord[s + 1];
final String read2 = hashmapWord[s + 2];
String readTrigrams = read + " " + read1;
HashMap<String, Integer> counter = hashmap.get(readTrigrams);
if (null == counter) {
counter = new HashMap<String, Integer>();
hashmap.put(readTrigrams, counter);
}
Integer count = counter.get(read2);
counter.put(read2, count == null ? 1 : count + 1);
}
}
br.close();
}
} catch (NullPointerException | IOException e) {
e.printStackTrace();
System.out.println("Unable to read files: " + e);
}
}
}
//COMPUTING THE TOTAL NUMBER OF WORDS FROM ALL THE TEXT FILES COMBINED
System.out.println("THE TOTAL NUMBER OF WORDS IN COLLECTED CORPUS IS : \t" + wordCount + "\n");
for(int i = 0, size = allWords.size(); i < size; i++){
String distinctWord = allWords.get(i);
//adding a word into the 'distinctWords' list if it doesn't already occur
if(!distinctWords.contains(distinctWord)){
distinctWords.add(distinctWord);
}
}
//PRINTING THE DISTINCT WORDS
System.out.println("THE DISTINCT WORDS IN TOTAL ARE :\t " + distinctWords.size() + "\n");
System.out.println("PRINTING CONTENTS OF THE BIGRAMS HASHMAP... ");
System.out.println(bigramMap);
System.out.println("================================================================================================================================================================================================================================================================================================================\n");
System.out.println("PRINTING CONTENTS OF THE TRIGRAMS HASHMAP... ");
System.out.println(hashmap);
System.out.println("================================================================================================================================================================================================================================================================================================================\n");
//QUITTING APPLICATION
String userInput = null;
while(true) {
System.out.println("\n**********************************************************************************************************************************************************************************************************************************");
System.out.println("\n\n\t\tPLEASE ENTER A WORD OR PHRASE YOU WOULD LIKE A PREDICTION OF THE NEXT WORD FROM:");
System.out.println("\t\t\t\t(OR TYPE IN 'Q' OR 'q' TO QUIT)");
userInput = input.nextLine();
if (userInput.equalsIgnoreCase("Q")) break;
//FORMAT USER INPUT
String[] users = userInput.toLowerCase().split("[?!,.\\s]+");
if (users.length < 2) {
userInput = users[0];
//System.out.println("\nENTRY '" + userInput + "' IS TOO SHORT TO PREDICT NEXT WORD. PLEASE ENTER 2 OR MORE WORDS");
//CALCULATING BIGRAM PROBABILITY
int sum = 0;
try {
for(String s : bigramMap.get(userInput).keySet()) {
sum += bigramMap.get(userInput).get(s);
}
String stringHolder = null;
double numHolder = 0.0;
for(String s : bigramMap.get(userInput).keySet()) {
//System.out.println("TWO");
double x = Math.round(bigramMap.get(userInput).put(s, bigramMap.get(userInput).get(s))/ (double)sum *100 );
if(s != null){
if(numHolder < x ){
stringHolder = s;
numHolder = x;
}
}
}
System.out.println("\nNEXT WORD PREDICTED IS '" + stringHolder + "'");
System.out.println("ITS PROBABILITY OF OCCURRENCE IS " + numHolder + "%");
} catch (Exception NullPointerException) {
System.out.println("\nSORRY. MATCH NOT FOUND.");
}
} else {
userInput = users[users.length - 2] + " " + users[users.length - 1];
// System.out.println("FROM USER WE GET....");
// System.out.println(bigrams.get(userInput).keySet());
/* CALCULATING TRIGRAM PROBABILITY*/
int sum = 0;
try {
for(String s : hashmap.get(userInput).keySet()) {
sum += hashmap.get(userInput).get(s);
}
String stringHolder = null;
double numHolder = 0.0;
for(String s : hashmap.get(userInput).keySet()) {
//System.out.println("TWO");
double x = Math.round(hashmap.get(userInput).put(s, hashmap.get(userInput).get(s))/ (double)sum *100 );
if(s != null){
if(numHolder < x ){
stringHolder = s;
numHolder = x;
}
}
}
System.out.println("\nNEXT WORD PREDICTED IS '" + stringHolder + "'");
System.out.println("ITS PROBABILITY OF OCCURRENCE IS " + numHolder + "%");
} catch (Exception NullPointerException) {
System.out.println("\nSORRY. MATCH NOT FOUND.");
}
}
}
input.close();
}
}
My first Jframe which i would like to appear upon running the project has got a single textbox and a single button;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String usersInput = jTextField1.getText();
Interface1 s = new Interface1();
s.setVisible(true);
dispose();
}
i would like for the user to enter data in the textbox and when they click on the button 'predict next word' then the output from the code execution is displayed on the second jframe which has got 3 labels and relative text areas.
NOTE; i couldn't paste the screenshots but if you run the NgramBetaE class you will get an idea of how the interfaces will be as i tried to explain them.
Thank you
Don't even try to link your GUI code to your NgramBetaE code as you've more work to do since the NgramBetaE is little more than one huge static main method that gets user input from the console with a Scanner and outputs to the console via printlns. Melding these two is like trying to put a square peg into a round hole.
Instead re-write the whole thing with an eye towards object-oriented coding, including creation of an OOP-compliant model class with instance fields and methods, and a single GUI that gets the input and displays it, that holds an instance of the model class and that calls instance methods on this instance.
Consider creating non-GUI classes and methods for --
Reading in data from your text files
Analyzing and hashing the data held in the text files including calculating word frequencies etc...
Returning needed data after analysis in whatever data form it may be needed.
A method for allowing input of a String/phrase for testing, with return its predicted probability
Then create GUI code for:
Getting selected text file from the user. A JFileChooser and supporting code works well here.
Button to start analysis
JTextField to allow entering of phrase
JTextArea or perhaps JTable to display results of analysis
Note that you should avoid having more than one JFrame in your GUI. For more on this, please have a look at The Use of Multiple JFrames, Good/Bad Practice?
I've got the following code that opens and read a file and separates it to words.
My problem is at making an array of these words in alphabetical order.
import java.io.*;
class MyMain {
public static void main(String[] args) throws IOException {
File file = new File("C:\\Kennedy.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
int line_count=0;
int byte_count;
int total_byte_count=0;
int fromIndex;
while( (line = br.readLine())!= null ){
line_count++;
fromIndex=0;
String [] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
String line_rest=line;
for (int i=1; i <= tokens.length; i++) {
byte_count = line_rest.indexOf(tokens[i-1]);
//if ( tokens[i-1].length() != 0)
//System.out.println("\n(line:" + line_count + ", word:" + i + ", start_byte:" + (total_byte_count + fromIndex) + "' word_length:" + tokens[i-1].length() + ") = " + tokens[i-1]);
fromIndex = fromIndex + byte_count + 1 + tokens[i-1].length();
if (fromIndex < line.length())
line_rest = line.substring(fromIndex);
}
total_byte_count += fromIndex;
}
}
}
I would read the File with a Scanner1 (and I would prefer the File(String,String) constructor to provide the parent folder). And, you should remember to close your resources explicitly in a finally block or you might use a try-with-resources statement. Finally, for sorting you can store your words in a TreeSet in which the elements are ordered using their natural ordering2. Something like,
File file = new File("C:/", "Kennedy.txt");
try (Scanner scanner = new Scanner(file)) {
Set<String> words = new TreeSet<>();
int line_count = 0;
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
line_count++;
String[] tokens = line.split(",\\s+|\\s*\\\"\\s*|\\s+|\\.\\s*|\\s*\\:\\s*");
Stream.of(tokens).forEach(word -> words.add(word));
}
System.out.printf("The file contains %d lines, and in alphabetical order [%s]%n",
line_count, words);
} catch (Exception e) {
e.printStackTrace();
}
1Mainly because it requires less code.
2or by a Comparator provided at set creation time
If you are storing the tokens in a String Array, use Arrays.sort() and get a naturally sorted Array. In this case as its String, you will get a sorted array of tokens.
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;
}
}