How to scan a file for a specific letter in Java - java

I need to take a file that a user chooses and scan that file for a letter that a user chooses, and then output how many times the user's letter appeared in the file.
I know how to get the user input and get the user to select a file, as well as scanning the file, but I cannot figure out a way to check each character within a file for a specific letter. The closest I have been able to come is this:
public class FileLetterCounter
{
public static void main(String[] args) throws IOException
{
int count = 0, stringLength;
String file, a = "a";
Scanner fileScanner, letterScan;
ArrayList<String> line = new ArrayList<String>();
fileScanner = new Scanner(new File("lab6.txt"));
while (fileScanner.hasNext())
{
line.add(fileScanner.next());
for (int index = 0; index < line.length(); index ++)
{
if (line.get(index).contains(a));
{
count++;
}
}
}
}
}
This doesn't work because the length() method does not work on an ArrayList, and I am unsure of how to approach the problem. I am asking this question because I found a similar one, but the recommended solution was to use what I have right now in my for loop (line.length()), but this won't work.

Instead of adding it to the list, just scan the text into a string, iterate each character of the string to check if the character matches with the search character, and increase the value of count for each match.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
int count = 0;
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the char to search: ");
char searchChar = keyboard.next().charAt(0);
Scanner fileScanner = new Scanner(new File("lab6.txt"));
while (fileScanner.hasNext()) {
String text = fileScanner.next();
for (int index = 0; index < text.length(); index++) {
if (text.charAt(index) == searchChar) {
count++;
}
}
}
System.out.println("The character " + searchChar + " appears " + count + " times in the file.");
fileScanner.close();
}
}

Look at this implementation with Streams. Looks pretty nice to me. Additionally do not forget to provide Charset, otherwise you could get unexpected results.
public static long countCharacterInFile(Path file, char ch, Charset charset) throws IOException {
try (Stream<String> stream = Files.lines(file, charset)) {
return stream.map(String::codePoints)
.flatMap(IntStream::boxed)
.filter(c -> c == ch)
.count();
}
}
Output:
Path file = Paths.get("lab6.txt");
System.out.println(countCharacterInFile(file, 'e', StandardCharsets.UTF_8)); // 666

Assuming you are trying to search a character in the whole file. Modified the code by removing all those unnecessary variables. Also I don't see any use of adding each line to a list of strings.
Idea is to scan through each line and increment count if the current character character matches your character
public class FileLetterCounter
{
public static void main(String[] args) throws IOException
{
int count = 0;
char targetLetter = 'a'; //define whatever you want or take it from user input
Scanner fileScanner = new Scanner(new File("lab6.txt"));
while (fileScanner.hasNext()) {
String line = fileScanner.nextLine();
for(int i=0; i<line.length(); i++) {
if(line.charAt(i) == targetLetter) {
count++;
}
}
}
System.out.println(count);
}
}

Related

Array of an List?

I have this code where I have an list of each sentence from the scanned text file, and it prints the sentences that end with ; and , And I'm wondering if I could make another array of each word in each sentence, so that I can scan the words instead of the sentences?
import java.io.*;
import java.util.*;
public class Main
{
public static void main(String args[]) throws IOException {
Scanner sf = new Scanner(new File("amazing.txt"));
List<String> text = new ArrayList<>();
while (sf.hasNextLine())
{
String current = sf.nextLine();
if (current.endsWith(",") || current.endsWith(";") || current.endsWith("!"))
System.out.println(current);
}
sf.close();
}
}
Usually we don't use Scanner Object to read a file as it's not a Best Practice check out this example as #Zabuzard pointed out .
Solution:
Scanner sf = new Scanner(new File("amazing.txt"));
List < String > text = new ArrayList < > ();
while (sf.hasNextLine()) {
String current = sf.nextLine();
// if (current.endsWith(",") || current.endsWith(";") || current.endsWith("!"))
// System.out.println(current);
String all_words[];
all_words = current.split(" "); //create an array with all strings seperated with space for each line
System.out.print("All words of the line:");
for (int i = 0; i < all_words.length; i++) {
System.out.print(all_words[i] + " ");
//after you do in this section your checks, add it to the List
}
System.out.println();
}
sf.close();
This will print all the words of each line. You can continue on with implementing your login in your case scenario and trim the strings to remove the special characters as well.
Then you can proceed by adding it to your List<String>.

what wrong with my code always print answer : null+word,what is null?

We have file with a few words, try safe word with word have 2,4,6 or 8 letters in array but then save in screen write null and null+good word.
What did I write wrong, and why does it show null?
public static void lyginis () throws IOException {
Path path = Paths.get("words.txt");
Scanner scanner = new Scanner(path);
int kiek = 0;
while (scanner.hasNext()) {
scanner.next();
kiek++;
}
Scanner scanner1 = new Scanner(path);
String[] atrinkti = new String[kiek];
String scan = "";
for (int i = 0; i < kiek; i++) {
scan = scanner1.next();
if (scan.length() % 2 == 0) {
atrinkti[i] += scan ;
}
System.out.println(atrinkti[i]);
}
}
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class Hello {
public static void main(String[] args) throws IOException {
File file = new File("words.txt");
Scanner scanner = new Scanner(file);
int kiek = 0;
while (scanner.hasNext()) {
scanner.next();
kiek++;
}
Scanner scanner2 = new Scanner(file);
String[] atrinkti = new String[kiek];
String word = "";
for (int i = 0; i < kiek; i++) {
word = scanner2.next();
if (word.length() % 2 == 0) {
atrinkti[i] = word;
System.out.println(atrinkti[i]);
}
}
}
}
Output
$ cat words.txt
hi
hello
whats up
chicken
duck
goose
$ javac Hello.java; java Hello
hi
up
duck
The issues were:
Path was used instead of File
The += was used within the if statement instead of just =
The System.out.println() function was called outside of the if statement so when the word's length was not divisible by 2, the current array element would print the default initialized value of the array of null

Changing input so in can take any length of string, problems with output

Currently I have a method that asks user for an input string but only outputs the first 16 characters! The method is supposed to take in any length of string then output the characters in 4x4 blocks after it does the following: first row remains the same. Shift the second row one position to the left, then shifts the third row two positions to the left. Finally, shift the fourth row three positions to the left. As of now it will only output the first 4x4 block
Also I am not sure how I can change the method so it doesnt ask for user input
I would like it to use a given string like:
String text = shiftRows("WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO");
"WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO" is the given encrypted string I would like to use. but without asking for user input..I keep getting errors and incorrect outputs..please show how I might fix this
code I am using:
public class shiftRows {
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
String[] input= new String[4];
String[] output= new String[4];
System.out.println("Enter a String");
String inputStr = sc.next();
for (int i = 0, n = 0; i < 4; i++, n+=4) {
input[i] = inputStr.substring(0+n, 4+n);
}
// -
output[0] = input[0];
for(int i=1; i<4; i++)
{
output[i] = Shift(input[i],i);
}
for(int i=0; i<4; i++)
{
System.out.println(output[i]);
}
}
public static String Shift(String str, int shiftNum)
{
char[] out = new char[4];
if(shiftNum==1)
{
out[0]=str.charAt(1);
out[1]=str.charAt(2);
out[2]=str.charAt(3);
out[3]=str.charAt(0);
}
if(shiftNum==2)
{
out[0]=str.charAt(2);
out[1]=str.charAt(3);
out[2]=str.charAt(0);
out[3]=str.charAt(1);
}
if(shiftNum==3)
{
out[0]=str.charAt(3);
out[1]=str.charAt(0);
out[2]=str.charAt(1);
out[3]=str.charAt(2);
}
return new String(out);
}
}
Here's a good way to do it :
import java.util.Scanner;
public class shiftRows {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String inputStr = "WVOGJTXQHUHXICWYYMGHTRKQHQPWKYVGLPYSPWGOINTOFOPMO";
for (int i = 0 ; i < inputStr.length() ; i++){
System.out.print(inputStr.charAt(i));
if ((i + 1)%4 == 0) System.out.println();
}
}
}
If you want to stock it into a String, just concatenate at each loop and add a "\n" each time the if test is valid.

How to count length of words in a File? Java

I am trying to write a code which would count the number of words of a certain length in a file.
For example:
How are you?
would print:
Proportion of 3-letter words: 100% (3 words)
I want to count words of length 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13+
Can you please guide me?
I am NOT trying to find the number of words. I am already able to do with this code:
public static int WordCount() throws FileNotFoundException
{
File file = new File("sample.txt");
Scanner keyboard = new Scanner(new FileInputStream(file));
int count=0;
while(keyboard.hasNext())
{
keyboard.next();
count++;
}
return count;
}
I want to find words of a certain length.
UPDATE
I have written the following code:
public static int WordLengthCount() throws FileNotFoundException
{
File file = new File("hello.txt");
Scanner keyboard = new Scanner(new FileInputStream(file));
int count5 = 0;
int hell = 0; //This is just for the else command to compile
while(keyboard.hasNext())
{
if ( keyboard.next().length() == 5 )
{
count5++;
keyboard.next();
return count5;
}
} return hell;
}
You can use the length() method to count the number of characters in a string (word). From there on, it's just a matter of saving it somewhere. E.g., in Map:
public static Map<Integer, Integer> lengthCounts() throws FileNotFoundException
Map<Integer, Integer> countMap = new HashMap<>();
while(keyboard.hasNext())
{
String word = keyboard.next();
int length = word.length();
Integer currCount = countMap.get(length);
if (currCount == null) {
countMap.put (length, 1);
else {
countMap.put (length, currCount + 1);
}
}
return countMap;
}
Now you could check the number of words with any particular length, or even print all of them.
EDIT:
If the only thing you need is the percentage of words of a certain length, all you need are two counters - one for the words of that length, and one for all the words:
public static double lengthPercentage(int requiredLength) throws FileNotFoundException
int allWords = 0;
int requiredWords = 0;
while(keyboard.hasNext())
{
String word = keyboard.next();
int length = word.length();
if (length == requiredLength) {
++requiredWords;
}
++allWords;
}
// implicit assumption: there's at least on word in the file
return ((double) requiredWords) / allWords;
}
File file = new File("sample.txt");
Scanner keyboard = new Scanner(new FileInputStream(file));
int count=0;
while(keyboard.hasNext())
{
keyboard.next();
// Use a hash map
// Check the string length and add it to the hash map by checking it already exists. If already exists then get the actual value from hashmap and increment it by one and save it again to the map.
count++;
}
So that your final output will be of map with one letter string count, two letter string count etc..
The other answers are great, but if you are trying to find words of a specific length in a file and you don't like the answers above, then you could also try REGEX. You can test each word and then do what you want with it. If you are looking for a count of words in a file of each length, I think the answer above is better, but if you're looking to detect a word of a specific length you could use .length() or the regex below. Using a strings .lenght() function in my opinion is better, but I'm just giving you an alternative answer and example.
I'll put a small example below.
public class Words{
public static void main(String [] args){
String [] words = {"Pizzaaa", "Pizza", "Party"};
int fives = 0;
for( String s : words){
if(s.matches(".{5}")){
5++;
}
}
System.out.println(fives);
}
}
Or a better version:
public class Words{
public static void main(String [] args){
String [] words = {"Pizzaaa", "Pizza", "Party"};
int fives = 0;
for( String s : words){
if(s.length() == 5){
5++;
}
}
System.out.println(fives);
}
}
Edited Below: To demonstrate how it can be used in a file based loop
// other code needed
while(in.hasNext())
{
String s = in.next();
if(s.length() == 5)
fives++;
}
For example, I have text file named TextFile.txt at C:\ has content:
Ut porttitor libero sodales quam sagittis, id facilisis lectus semper.
and Java code:
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Example {
public static void main(String[] args) throws IOException {
File file = new File("C:\\TextFile.txt");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
if (dis.available() != 0) {
// Get the line.
String s = dis.readLine();
// Put words to array.
String[] sParts = s.split(" ");
// Initialize word longest length.
int longestLength = 1;
for (String strx : sParts) { // Go through each sPart, the next one is called strx
// If the document has word longer than.
if (longestLength < strx.length())
// Set new value for longest length.
longestLength = strx.length();
}
// Because array index from "0".
int[] counts = new int[longestLength + 1];
for (String str : sParts) {
// Add one to the number of words that length has
counts[str.length()] += 1;
}
// We use this type of loop since we need the length.
for (int i = 1; i < counts.length; i++) {
System.out.println(i + " letter words: " + counts[i]);
}
}
}
}
// Result:
// 1 letter words: 0
// 2 letter words: 2
// 3 letter words: 0
// 4 letter words: 1
// 5 letter words: 0
// 6 letter words: 2
// 7 letter words: 2
// 8 letter words: 0
// 9 letter words: 3

Refine code. Search Strings

So the code I have is for a homework assignment where the user inputs a sentence (string) and I need to search through the string and return the smallest word. However, there must be a number inputted at the first spot in the string. Ex: "4 WHAT IS THIS". Output should be "IS" and ignore the number. The only way I figured out how to ignore the number is to make the loop skip over the first spot where the number would be. It works by itself but whenever I put it into the rest of my program it stops working. Is there anyway to make this program cleaner?
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// Lexicographically smallest word
String TheSentence = sc.nextLine();
String[] myWords = TheSentence.split(" ");
int shortestLengths, shortestLocation;
shortestLengths = (myWords[1]).length();
shortestLocation = 1;
for (int i = 1; i < myWords.length; i++) {
if ((myWords[i]).length() < shortestLengths) {
shortestLengths = (myWords[i]).length();
shortestLocation = i;
}
}
System.out.println(myWords[shortestLocation]);
}
Inside your for loop (that should start at i = 0), add code like this:
try {
double value = Double.parseDouble(myWords[i]);
} catch (NumberFormatException e) {
// add the rest of your code here
}
The idea is that you try to transform your word to a number and if you fail, it means it's not a number, so you can use the length logic on the word.
The first thing you should do is to create the function you want to use instead of mixing the relevant code for the exercice with things like reading a line from the input stream.
You can test whether a character is a letter using Character.isLetter(char).
A good exercice is to build a solution using only that function and looking at each character separately (String.charAt(int) method) in a loop.
The solution is to remember where the currently shortest word starts and how long it is.
In practice, I would just use regexes like this:
public static String shortestWord(String sentence) {
String shortest = null;
Pattern word = Pattern.compile("\\w+");
Matcher m = word.matcher(sentence);
while (m.find()) {
String candidate = m.group();
if (shortest == null || shortest.length() > candidate.length())
shortest = candidate;
}
return shortest;
}
You could try using substring, e.g.
String result=inputString.substring(1)
'1' being the second letter in the string, substring returning every value save for the first.
The below basically just shortens up your code..other than that it doesn't change much. That being said..it would be much better to create all this in a method called shortestWord() or something. There is really no reason the code below shouldn't work though.
Revised Code:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] myWords = (sc.nextLine()).split(" ");
int shortestLocation = 1
for (int i = 2; i < myWords.length; i++) { // No reason to start at 1 as you have
// already made shortestLocation = 1
if (myWords[i].length() < myWords[shortestLocation].length()) {
shortestLocation = i;
}
}
System.out.println(myWords[shortestLocation]);
}
Suggested Code:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] myWords = (sc.nextLine()).split(" ");
System.out.println("The shortest word is: " + shortestWord(myWords));
}
public static String shortestWord(String[] myWords) {
int shortestLocation = 1
for (int i = 2; i < myWords.length; i++) { // No reason to start at 1 as you have
// already made shortestLocation = 1
if (myWords[i].length() < myWords[shortestLocation].length()) {
shortestLocation = i;
}
}
return myWords[shortestLocation];
}

Categories

Resources