File letter counter errors - java

Write a program that asks the user to enter the name of a file, and then asks the user to enter a character. The program should count and display the number of times that the specified character appears in the file.
My problem is that length and charAt on lines 24 and 25 error, and I'm not sure what to do in order to get the program to run.
import java.util.Scanner;
import java.io.*;
public class challenge6 {
public static void main(String[] args) throws Exception {
String string;
char character;
int count = 0;
File file = new File("./file.txt");
Scanner input = new Scanner(file);
input.hasNextLine();
while (input.hasNextLine())
System.out.println(input.nextLine());
System.out.println("enter name of a char");
character = input.next().charAt(0);
for(int i=0; i < input.length(); i++)
{ if(input.charAt(i) == character)
count++;
}
System.out.println(count);}}

An easier way would be to utilize the String::replace method to replace char with blank and check to string length before and after. You also need to loop all through your file
File f = new File("c:/tmp/file.txt");
Scanner input = new Scanner(f);
int count = 0;
String charToFind = "a";
while (input.hasNextLine()) {
String line = input.nextLine();
int len = line.length();
line = line.replace(charToFind, "");
count += len - line.length();
}
System.out.format("There were %d occurrences found%n", count);
input.close();

Related

Prevent JUnit test from getting stuck in while-loop

I'm currently writing some JUnit tests for some assignments on Replit.com's Teams for education. I have a test that's getting stuck, I believe, because of a while loop in the main method. If the first input is valid, according to the program, the test runs. If the first input is invalid, the test gets stuck.
Here's the test:
#Test
public void validPW(){
String correctOutput = "Enter a password >> Not enough uppercase letters!\nNot enough digits!\nReEnter a password >> Valid password\nGoodbye!";
try{
// IMPORTANT: Save the old System.out!
PrintStream old = System.out;
// Create a stream to hold the output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//PrintStream ps = new PrintStream(baos);
System.setOut(new PrintStream(baos, false, "UTF-8"));
// IMPORTANT: save old Sytem.in!
InputStream is = System.in;
// Set new System.in
System.setIn(new ByteArrayInputStream("Iljvm4\nVaGN76js\n".getBytes()));
// Calling main method should save main method's output as string literal to baos.
String[] requiredArray = {"Hello", "There"};
ValidatePassword.main(requiredArray);
// Put things back
System.out.flush();
System.setOut(old);
//Restore
System.setIn(is);
assertEquals(correctOutput, baos.toString());
}catch(IOException ioe){
new IOException("i/o problem - test not executed\n");
}
}
Here's the program:
import java.util.*;
public class ValidatePassword {
public static void main(String[] args) {
String passWord;
boolean Valid = false;
final int NUM = 2; // two digits and two Upper case letters
// counters to count the required digits and letters
int upperCount = 0;
int lowerCount = 0;
int digitCount = 0;
while (!Valid) {
Scanner in = new Scanner(System.in);
int numSpaces = 0;
System.out.print("Enter a password >> ");
passWord = in.next();
in.nextLine(); // capture dangling newline char.
// Using a for loop to iterate over each character in the String
for (int i = 0; i < passWord.length(); i++) {
char ch = passWord.charAt(i);
if (Character.isUpperCase(ch)){ // Using the Character class's methods
upperCount++;
}
else if (Character.isLowerCase(ch)){
lowerCount++;
}
else if (Character.isDigit(ch)){
digitCount++;
}
}
if (upperCount >= NUM && lowerCount >= 3 && digitCount >= NUM) {
System.out.println("Valid password\nGoodbye!");
Valid = true;
} else {
if (upperCount < NUM)
System.out.println("Not enough uppercase letters!");
if (lowerCount < 3)
System.out.println("Not enough lowercase letters!");
if (digitCount < NUM)
System.out.println("Not enough digits!");
System.out.print("Re");
// Resetting the counters if not a valid password
upperCount = 0;
lowerCount = 0;
digitCount = 0;
}
}
}
}
First, the code in ValidatePassword tries to read the input stream beyond its end, so the scanner initialization needs to be moved out of the loop and a condition in.hasNextLine() needs to be checked.
Also, it's better to use a single reading of the line passWord = in.nextLine(); instead of a pair in.next(); in.nextLine();.
These two fixes should resolve the issue with incorrect loop.
Scanner in = new Scanner(System.in);
while (!Valid && in.hasNextLine()) {
int numSpaces = 0;
System.out.print("Enter a password >> ");
passWord = in.nextLine();
//in.nextLine(); // capture dangling newline char.
// ... keep the rest as is
And the last, correctOutput needs to be fixed for assertEquals to complete successfully.

Random String Generator keeps adding to previous iterations

I am writing a program that takes a user's input for a string that must be of length 6, and creates a random version of that string. Then, it prints out 5-10 iterations of a randomised string. For example:
The input of 8 and abcdef would create 8 lines of random variations of abcdef. The program below does that, but it's adding strings together, as so:
abbdfe
abbdfeacbfed
and so on. Does anyone know how to change it so it would print abbdfe acbfed and so on.
I know there are some functional issues with my code but it works as a start.
package matrixMaker;
import java.util.Scanner;
import java.util.Random;
public class matrixMaker
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter a number between 5 and 10, inclusively: ");
int userInput = in.nextInt();
in.nextLine();
System.out.print("Please enter a string of length 6 characters: ");
String textToChange = in.nextLine();
String randomText = "";
int length = 6;
// Print error if text is not 6 characters long.
while(textToChange.length() != 6)
{
System.out.println("Error! Enter a string of length 6.");
}
// If input is 6 characters, print out randomText X amount of times, depending on the user's specification of user.
if(textToChange.length() == 6)
{
for (int i = 1; i <= userInput; i++)
{
// Initialise array to create random order of chars.
Random rand = new Random();
char[] text = new char[length];
for(int a = 0; a < length; a++)
{
text[a] = textToChange.charAt(rand.nextInt(textToChange.length()));
}
// Take the chars from array and concatenate them into a string of the same size as the text variable.
for(int a = 0; a < text.length; a++)
{
randomText += text[a];
}
System.out.printf(randomText + "\n");
}
}
in.close();
}
}
You seem to be initializing the variable randomText at the top of the method, but keep adding to the same variable inside the loop, so it will keep adding to itself.
String randomText = "";
randomText += text[a];
Either initialize the randomText String inside the loop, or after your last line inside the loop, assign it back to an empty string again.
Btw, you seem to have another error here:
// Print error if text is not 6 characters long.
while(textToChange.length() != 6)
{
System.out.println("Error! Enter a string of length 6.");
}
This loop will go for infinite, you need to add a way to allow the user to change the input after the error is displayed.
while(textToChange.length() != 6)
{
System.out.println("Error! Enter a string of length 6.");
in.nextLine();
textToChange = in.nextLine();
}
--Edit added to OP comment:
To print the character of the odd generated text on the odd row number; one way to do it is to consider pushing your generated randomText to an empty ArrayList which you initialize outside the loop..then you can loop over your ArrayList separately. You can think of ways to refactor this and put in an outside method in the way you like. like this:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Please enter a number between 5 and 10, inclusively: ");
int userInput = in.nextInt();
in.nextLine();
System.out.print("Please enter a string of length 6 characters: ");
String textToChange = in.nextLine();
int length = 6;
// Print error if text is not 6 characters long.
while (textToChange.length() != 6) {
System.out.println("Error! Enter a string of length 6.");
in.nextLine();
textToChange = in.nextLine();
}
//new array list for results of random text generated
ArrayList<String> randomTextArray = new ArrayList<>();
// If input is 6 characters, print out randomText X amount of times, depending on the user's specification of user.
if (textToChange.length() == 6) {
for (int i = 1; i <= userInput; i++) {
String randomText = "";
// Initialise array to create random order of chars.
Random rand = new Random();
char[] text = new char[length];
for (int a = 0; a < length; a++) {
text[a] = textToChange.charAt(rand.nextInt(textToChange.length()));
}
// Take the chars from array and concatenate them into a string of the same size as the text variable.
for (int a = 0; a < text.length; a++) {
randomText += text[a];
}
randomTextArray.add(randomText);
System.out.printf(randomText + "\n");
}
System.out.printf("Odd Characters \n");
String oddCharsOfRandomText = "";
for (int i=0; i < randomTextArray.size(); i++) {
if (!(i%2 == 0)) { //resolve true only if we are in an odd line
for (int x=0; x <= randomTextArray.get(i).length(); x++ ){
if (!(x%2 == 0)) { //resolve true only if we are in an odd character
oddCharsOfRandomText += randomTextArray.get(i).charAt(x);
}
}
}
}
System.out.printf(oddCharsOfRandomText + "\n");
}
in.close();
}

Cant understand why i am getting an infinite loop. Java. How to trigger EoF without typing exit

I am very new to java and this community. I am looking for someone to possibly be able to explain why my code is going into an infinite loop. I believe it has something to do with my while loop. The program compiles but when I enter a phrase i want for my acronym builder to create the program dosent do anything, it just blinks at the next line. When i press ctrl c to exit, it then shows the acronym.
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class Acronym{
public static void main(String[] args) {
String phraseToChange = "";
int wordCounter = 0;
char[] acroynmArray = new char [100];
Scanner input = new Scanner(System.in);
System.out.println("This program builds acronyms");
System.out.println("Enter a phrase:");
while (input.hasNext() )
{
phraseToChange = input.next();
acroynmArray[wordCounter] = phraseToChange.charAt(0);
wordCounter++;
}
for (int i = 0;i < wordCounter ; i++ )
{
System.out.print(acroynmArray[i]);
}
}
}
The problem is not truly caused by your while loop but because the fact that scanner will keep asking user new input (system.in stream will always open) until EOF. Therefore, the problem can be solve using StringTokenizer if it's allowed by your professor. Down here is the code example
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class Acronym{
public static void main(String[] args) {
String phraseToChange = "";
boolean phraseToChange2 = true;
int wordCounter = 0;
char[] acroynmArray = new char [100];
Scanner input = new Scanner(System.in);
System.out.println("This program builds acronyms");
System.out.println("Enter a phrase:");
String nextLine = input.nextLine();
StringTokenizer st = new StringTokenizer(nextLine, " ");
while (st.hasMoreTokens())
{
phraseToChange = st.nextToken();
acroynmArray[wordCounter] = phraseToChange.charAt(0);
wordCounter++;
}
System.out.println("reach here");
for (int i = 0;i < wordCounter ; i++ )
{
System.out.print(acroynmArray[i]);
}
}
}
The reason of why your loop never ends it the fact that System.in stream is always open. You should change the condition to while (!phraseToChange.equals("exit")) or something. Then the user will be able to finish the input by sending "exit" string to your program.
If you don't have to use a while loop with input.hasNext() you can use this. May want to clean up where necessary, but I believe this does what you want.
import java.util.Scanner;
import java.io.*;
import java.util.*;
public class Acronym {
public static void main(String[] args) {
String phraseToChange = "";
int wordCounter = 0;
char[] acroynmArray = new char[100];
Scanner input = new Scanner(System.in);
System.out.println("This program builds acronyms");
System.out.println("Enter a phrase:");
String[] line = input.nextLine().split(" ");
for (int i = 0; i < line.length; i++) {
phraseToChange = line[i];
acroynmArray[i] = phraseToChange.charAt(0);
wordCounter++;
}
for (int i = 0; i < wordCounter; i++) {
System.out.print(acroynmArray[i]);
}
}
}
Sample build output:
run:
This program builds acronyms
Enter a phrase:
Google Rocks Socks
GRSBUILD SUCCESSFUL (total time: 4 seconds)
Code snippet that causes the change:
String[] line = input.nextLine().split(" ");
for (int i = 0; i < line.length; i++) {
phraseToChange = line[i];
acroynmArray[i] = phraseToChange.charAt(0);
wordCounter++;
}
Alternatively you could use this:
public static void main(String[] args) {
String phraseToChange = "";
int wordCounter = 0;
char[] acroynmArray = new char [100];
Scanner input = new Scanner(System.in);
System.out.println("This program builds acronyms");
System.out.println("Enter a phrase:");
String line = input.nextLine(); // Obtain user entered line
acroynmArray[0] = line.charAt(0); // First letter is known; set it
wordCounter++; // increment wordCounter
//Loop the characters in the retrieved line
for(int i = 0; i < line.length(); i++){
// If it's whitespace then we know the next character must be the letter we want
if(Character.isWhitespace(line.charAt(i))){
acroynmArray[wordCounter] = line.charAt(i+1); // Set it
wordCounter++;
}
}
But as Tom said in my deleted post, this is quite fragile code. It works, until it doesn't, as in it wouldn't take much to break it as it doesn't handle trailing and starting whitespaces

How do I remove odd ASCll characters from a String in a text file?

I hope I am making sense but, I am trying to figure out how to read a String/input in a text file so that I can remove the odd letters in it. So for example 'a' would be 1, 'b' would be 2, 'c' would be 3 and so on. So in my text file I have written in it "Hello, world!". The final output is supposed to be Hll, rld!
I really need some help because I'm struggling pretty hard and have just been staring at my computer for some hours getting nowhere, trying to figure this out. Heres what I have so far(basically nothing), I am terrible at fileprocessing.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class readodds {
public static void main (String[]args) throws FileNotFoundException {
Scanner console = new Scanner(System.in);
String letter= new String();
System.out.println("Name of file: ");
String inputFile = console.next();
File file = new File(inputFile);
Scanner in = new Scanner(file);
System.out.println(in.nextLine());
while(in.hasNext()) {
String line = in.nextLine();
}
}
}
Let the JDK do the heavy lifting for you. It can all be done in one line:
Files.lines(Paths.get(inputFile))
.map(s -> s.replaceAll("(?i)[acegikmoqsuwy]",""))
.forEach(System.out::println);
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class readodds {
public static void main (String[]args) throws FileNotFoundException {
Scanner console = new Scanner(System.in);
String letter= new String();
System.out.println("Name of file: ");
String inputFile = console.next();
File file = new File(inputFile);
Scanner in = new Scanner(file);
while(in.hasNext()) {
String line = in.nextLine();
line = line.replaceAll("a","1"); //This replaces every a with a 1
System.out.println(line);
}
}
}
You can duplicate the call for line.replaceAll("a","1") for every other letter you want to change. If you want to remove a letter: line.replaceAll("a","");
You can loop through the String and print only the even letters by comparison.
while (in.hasNext()) {
String line = in.nextLine();
for (int i = 0; i < line.length(); i++) {
char letter = line.charAt(i);
if (Character.toUpperCase(letter) >= 'A' && Character.toUpperCase(letter) <= 'Z' && ('Z' - Character.toUpperCase(letter)) % 2 == 0)
System.out.print(letter);
}
}
you can use asci integer value of character. e.g
character "a" equivalent int value is 97, b's 98 and so on..
you can do the following code to get transformed line for each of the line of file..
then write the new transformed line to output temporary file
public static void main(String[] argv) {
System.out.println(removedOddLetter("Hello, world!"));
}
public static String removedOddLetter(String test){
int aNum='a';
int ANum='A';
int zNum='z';
int ZNum='Z';
char[] bArr=test.toCharArray();
StringBuilder outLines=new StringBuilder();
for(int i=0;i<bArr.length;i++){
// if the character is alphabet
if (bArr[i] >= aNum && bArr[i] <= zNum){
// offSet is zero for odd letter like a
int offSet=bArr[i]-aNum;
// if bArr[i] is not odd letter
if((offSet%2) ==1){
outLines.append(bArr[i]);
}
}
// similarly for Capital characters
else if (bArr[i] >= ANum && bArr[i] <= ZNum){
// offSet is zero for odd letter like a
int offSet=bArr[i]-ANum;
// if bArr[i] is not odd letter
if((offSet%2) ==1){
outLines.append(bArr[i]);
}
}
else {
// any other character copy the content
outLines.append(bArr[i]);
}
}
return outLines.toString();
}
your While loop will be as
while(in.hasNext()) {
String line = in.nextLine();
char[] arr = s.toCharArray ();
for (char c: arr) {
if ((c % 2) == 0) {
System.out.print (c);
}
}
}

Counting a specific char in java, but my program only reads the first character in a word

I have a program that is supposed to count all the instances of a specific character, like 'A', in a specified file. I got it to count the characters, sort of, except it only looks at the character at the beginning of a word. So "a a aaa a ba" would only count as 4 "A"s and not 7. I've commented as best as I can so my train of thought is clear, but I'm fairly new to programming so I apologize in advance if I'm not being clear.
import java.util.Scanner;
import java.io.*;
public class Charcounter
{
public static void main(String[] args) throws IOException
{
//accumulator
int sum = 0;
Scanner kb = new Scanner(System.in);
//get filename and character to be counted from user
System.out.println("Enter the name of a file: ");
String filename = kb.nextLine();
System.out.println("Enter the name of the character to be counted: ");
char countedChar = kb.next().charAt(0);
//check if file exists
File file = new File(filename);
if (!file.exists())
{
System.out.println("File specified not found.");
System.exit(0);
}
//open file for reading
Scanner inputFile = new Scanner(file);
//read file and count number of specified characters
while (inputFile.hasNext())
{
//read a char from the file
char count = inputFile.next().charAt(0);
//count the char if it is the one specified
if (count == countedChar)
{
++sum;
}
}
//close file
inputFile.close();
//display number of the specified char
System.out.println("The number of the character '" + countedChar + "' is : " + sum);
}
}
It is because you are only comparing the first character.
//read a char from the file
// THIS : only the first character
char count = inputFile.next().charAt(0);
//count the char if it is the one specified
if (count == countedChar)
{
++sum;
}
You should loop through all the characters and then increment the sum if it matches the countedChar, something like..
String str = inputFile.next()
for (int i = 0; i < str.length(); i++) {
char count = str.charAt(i);
// check if it matches the countedChar and then increment.
}
Thats because you are only reading the first char
String word = inputFile.next(); //read a word
int counter = 0;
for(counter=0;counter<word.length();counter++) // traverse through the word
{
char count = word.charAt(i); // ith char
//count the char if it is the one specified
if (count == countedChar)
{
++sum;
}
}
Try using a variable instead of zero which initializes as zero in the beginning of the class and then increment it for every char it counts, so:
//read a char from the file
char count = inputFile.next().charAt(m);
++m;
//count the char if it is the one specified
if (count == countedChar)
{
++sum;
}
And then in the main method define:
int m = 0
It is because you are using
char count = inputFile.next().charAt(0);
By default next will read until it will find whitespace or end of data so now it reads and returns entire words.
If you want to make this approach work you need next to return only one character at a time so set delimiter in imputFile scanner to empty string like inputFile.useDelimiter("");.
while (inputFile.hasNext()) {
String word = inputFile.next();
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == countedChar) {
++sum;
}
}
}
As alternative you can use a Reader that is dedicated to char reading:
BufferedReader reader = new BufferedReader(new FileReader(file));
int read;
while((read = reader.read())>0) if (read==countedChar) count++;
reader.close();

Categories

Resources