Reputation: 39
I am trying to take input from a user, and print the amount of lines, words, and characters in a text file. However, only the amount of words is correct, it always prints 0 for the lines and characters.
import java.util.*;
import java.io.*;
public class TextFileInfoPrinter
{
public static void main(String[]args) throws FileNotFoundException
{
Scanner console = new Scanner(System.in);
System.out.println("File to be read: ");
String inputFile = console.next();
File file = new File(inputFile);
Scanner in = new Scanner(file);
int words = 0;
int lines = 0;
int chars = 0;
while(in.hasNext())
{
in.next();
words++;
}
while(in.hasNextLine())
{
in.nextLine();
lines++;
}
while(in.hasNextByte())
{
in.nextByte();
chars++;
}
System.out.println("Number of lines: " + lines);
System.out.println("Number of words: " + words);
System.out.println("Number of characters: " + chars);
}
}
Upvotes: 3
Views: 104372
Reputation: 1
import java.io.*;
class wordcount
{
public static int words=0;
public static int lines=0;
public static int chars=0;
public static void wc(InputStreamReader isr)throws IOException
{
int c=0;
boolean lastwhite=true;
while((c=isr.read())!=-1)
{
chars++;
if(c=='\n')
lines++;
if(c=='\t' || c==' ' || c=='\n')
++words;
if(chars!=0)
++chars;
}
}
public static void main(String[] args)
{
FileReader fr;
try
{
if(args.length==0)
{
wc(new InputStreamReader(System.in));
}
else
{
for(int i=0;i<args.length;i++)
{
fr=new FileReader(args[i]);
wc(fr);
}
}
}
catch(IOException ie)
{
return;
}
System.out.println(lines+" "+words+" "+chars);
}
}
Upvotes: 0
Reputation: 11
I think the best answer is
int words = 0;
int lines = 0;
int chars = 0;
while(in.hasNextLine()) {
lines++;
String line = in.nextLine();
for(int i=0;i<line.length();i++)
{
if(line.charAt(i)!=' ' && line.charAt(i)!='\n')
chars ++;
}
words += new StringTokenizer(line, " ,").countTokens();
}
Upvotes: 1
Reputation: 465
while(in.hasNextLine()) {
lines++;
String line = in.nextLine();
for(int i=0;i<line.length();i++)
{
if(line.charAt(i)!=' ' && line.charAt(i)!='\n')
chars ++;
}
words += new StringTokenizer(line, " ,;:.").countTokens();
}
Upvotes: 0
Reputation: 9577
You could use regular expressions to count for you.
String subject = "First Line\n Second Line\nThird Line";
Matcher wordM = Pattern.compile("\\b\\S+?\\b").matcher(subject); //matches a word
Matcher charM = Pattern.compile(".").matcher(subject); //matches a character
Matcher newLineM = Pattern.compile("\\r?\\n").matcher(subject); //matches a linebreak
int words=0,chars=0,newLines=1; //newLines is initially 1 because the first line has no corresponding linebreak
while(wordM.find()) words++;
while(charM.find()) chars++;
while(newLineM.find()) newLines++;
System.out.println("Words: "+words);
System.out.println("Chars: "+chars);
System.out.println("Lines: "+newLines);
Upvotes: 0
Reputation: 46728
in.next();
is consuming all the lines in the first while()
. After the end of your first while loop, there are no more characters to be read at the input stream.
You should nest your character and word-counting within a while loop counting lines.
Upvotes: 2
Reputation: 881243
Is there some reason why you think that:
while(in.hasNext())
{
in.next();
words++;
}
will not consume the entire input stream?
It will do so, meaning that your other two while
loops will never iterate. That's why your values for words and lines are still set to zero.
You're probably better off reading the file one character at a time, increasing the character count each time through the loop, and also detecting the character to decide whether or not to increment the other counters.
Basically, wherever you find a \n
, increase the line count - you should probably also do this if the last character in the stream wasn't \n
.
And, whenever you transition from white-space to non-white-space, increase the word count (there'll probably be some tricky edge case processing at the stream beginning but that's an implementation issue).
You're looking at something like the following pseudo-code:
# Init counters and last character
charCount = 0
wordCount = 0
lineCount = 0
lastChar = ' '
# Start loop.
currChar = getNextChar()
while currChar != EOF:
# Every character counts.
charCount++;
# Words only on whitespace transitions.
if isWhite(lastChar) && !isWhite(currChar):
wordCount++
# Lines only on newline characters.
if currChar == '\n':
lineCount++;
lastChar = currChar
currChar = getNextChar()
# Handle incomplete last line.
if lastChar != '\n':
lineCount++;
Upvotes: 1
Reputation: 15515
I agree with @Cthulhu answer. In your code you can reset your Scanner
object (in
).
in.reset();
This will reset your in object at the first line of your file.
Upvotes: 0
Reputation: 135992
try
int words = 0;
int lines = 0;
int chars = 0;
while(in.hasNextLine()) {
lines++;
String line = in.nextLine();
chars += line.length();
words += new StringTokenizer(line, " ,").countTokens();
}
Upvotes: 6
Reputation: 15632
I'm no Java expert, but I would presume that the .hasNext
, .hasNextLine
and .hasNextByte
all use and increment the same file position indicator. You'll need to reset that, either by creating a new Scanner as Aashray mentioned, or using a RandomAccessFile and calling file.seek(0);
after each loop.
Upvotes: 0
Reputation: 2753
The file pointer is set to the end of the file when the 1st while is executed. try this:
Scanner in = new Scanner(file);
while(in.hasNext())
{
in.next();
words++;
}
in = new Scanner(file);
while(in.hasNextLine())
{
in.nextLine();
lines++;
}
in = new Scanner(file);
while(in.hasNextByte())
{
in.nextByte();
chars++;
}
Upvotes: 0