I'm trying to write a method, which checks if a given string exists in a .txt file, but it seems like my if/else statement isn't working correctly.
public void ChcekIfPasswordExsists(String check) throws FileNotFoundException{
BufferedReader reader = new BufferedReader(new FileReader("Passwords.txt"));
Scanner fileScanner = new Scanner(reader);
while(fileScanner.hasNextLine()){
final String line = fileScanner.next();
if(line.contains(check)){
System.out.println("Password for " + check + " already exsits");
break;
}
else{
System.out.println(check + " is usable");
break;
}
}
}
This is where I'm calling the method:
System.out.println("Enter the name of the app or website,\nwhere password is going to be use:");
useCase = s.nextLine();
ChcekIfPasswordExsists(useCase);
I have looked at countless other posts with no effect. No matter what, it seems like the code skips the "if" statement and directly jumps to the "else" statement.
The logic of your while loop should be to iterate over all lines in the file until either you find a match or you hit the end of the file. Consider this version:
public void ChcekIfPasswordExsists(String check) throws FileNotFoundException {
BufferedReader reader = new BufferedReader(new FileReader("Passwords.txt"));
Scanner fileScanner = new Scanner(reader);
boolean flag = false;
while (fileScanner.hasNextLine()) {
final String line = fileScanner.next();
if (line.contains(check)) {
flag = true;
break;
}
}
if (flag) {
System.out.println("Password for " + check + " already exsits");
}
else {
System.out.println(check + " is usable");
}
}
Also, I might be inclined to change the method signature to return a boolean value (true/false). Based on that return value, you can display to the console the message you want.
Side note: If you are actually storing cleartext passwords in a text file, then stop doing that immediately. It is a security hole. Instead, setup a proper database and only store an irreversible hash of the passwords.
Related
So I'm working on a project that requires me to compare a users input to a list of words in a txt file. I've been trying to compare the the input as a string to the BufferReader, but it hasn't been working. Any suggestions is welcomed
Here's the code for the project
public class Lab5Program1 {
public static void main(String[] args) throws IOException {
File file = new File("fileName");
BufferedReader br = new BufferedReader(new FileReader(file));
/** In order to read a text file that is inside the package, you need to call the actual file and then pass it
* to the BufferedReader. So that it can be used in the file**/
// String[] wordArray = { "hello", "goodbye", "cat", "dog", "red", "green", "sun", "moon" };
String isOrIsNot, inputWord;
// This line asks the user for input by popping out a single window
// with text input
inputWord = JOptionPane.showInputDialog(null, "Enter a word in all lower case:");
// if the inputWord is contained within wordArray return true
if (wordIsThere(inputWord, br))
isOrIsNot = "is"; // set to is if the word is on the list
else
isOrIsNot = "is not"; // set to is not if the word is not on the list
// Output to a JOptionPane window whether the word is on the list or not
JOptionPane.showMessageDialog(null, "The word " + inputWord + " " + isOrIsNot + " on the list.");
} //main
public static boolean wordIsThere(String findMe, BufferedReader bufferedReader) throws IOException {
// for (int i = 0; i < bufferedReader.lines() ; i++){
// if (findMe.equals(theList[i])){
// return true;
// }
// }
while((findMe = bufferedReader.readLine()) != null) {
if (findMe.equals(bufferedReader.readLine())){
return true;
}
}
return false;
} // wordIsThere
}
The error is coming from the function to check if the word exists. Each line being reader from the text file is not being checked with findMe. Made these changes, it works.
public static boolean wordIsThere(String findMe, BufferedReader br) throws IOException {
for (String word = br.readLine() ; word != null; word = br.readLine()) {
if (word.equals(findMe))
return true;
}
return false;
}
In method wordIsThere, parameter findMe is the word you are looking for. However you overwrite the value of the parameter with the line read from the file.
You should declare a separate variable to store the line of text that you read from the file.
public static boolean wordIsThere(String findMe, BufferedReader bufferedReader) throws IOException {
String line = bufferedReader.readLine(); // read first line of file
while(line != null) {
if (findMe.equals(line)){
return true;
}
line = bufferedReader.readLine(); // read next line of file
}
return false;
}
Also note that since you are using JOptionPane to get user input, a separate thread is launched and this thread does not terminate when method main terminates. Hence you should call method exit, of class java.lang.System in the last line of main, in class Lab5Program1. Otherwise, each time you run class Lab5Program1 you will start a new JVM that will not terminate.
For console applications, you can use class java.util.Scanner to get user input.
Scanner stdin = new Scanner(System.in);
System.out.print("Enter a word in all lower case: ");
String inputWord = stdin.nextLine();
Also consider closing files when you have finished with them. In your case it is not necessary since the file is automatically closed when the JVM terminates.
I have read in a text file and am scanning said file. The question I have is how would I skip over lines that include a certain character (in my case lines that start with " // " and " " (whitespace).
Here is my code at the moment. Can someone point me in the right direction?
File dataFile = new File(filename);
Scanner scanner = new Scanner(dataFile);
while(scanner.hasNext())
{
String lineOfText = scanner.nextLine();
if (lineOfText.startsWith("//")) {
System.out.println(); // not sure what to put here
}
System.out.println(lineOfText);
}
scanner.close();
You will only want to execute the code within the while-loop if the line of text doesn't start with a / or whitespace. You can filter these out as seen below:
while(scanner.hasNext()) {
String lineOfText = scanner.nextLine();
if (lineOfText.startsWith("//") || lineOfText.startsWith(" ")) {
continue; //Exit this iteration if line starts with space or /
}
System.out.println(lineOfText);
}
As you are iterating over the lines of text in the file, use String's startsWith() method to check if the line starts with the sequences you are trying to avoid.
If it does, continue to the next line. Otherwise, print it.
while (scanner.hasNext()) {
String lineOfText = scanner.nextLine();
if (lineOfText.startsWith("//") || lineOfText.startsWith(" ") ) {
continue;
}
System.out.println(lineOfText);
}
Just use a continue like -
if (lineOfText.startsWith("//")) {
continue; //would skip the loop to next iteration from here
}
Detials - What is the "continue" keyword and how does it work in Java?
If you're just interested in printing out the lines of code that begin with a "//" then you should just use the continue keyword in java.
String lineOfText = scanner.nextLine();
if (lineOfText.startsWith("//")) {
continue;
}
See this post for more information regarding the "continue" keyword.
You can just insert "else" in your code like:
public static void main(String[] args) throws FileNotFoundException {
File dataFile = new File("testfile.txt");
Scanner scanner = new Scanner(dataFile);
while(scanner.hasNext())
{
String lineOfText = scanner.nextLine();
if (lineOfText.startsWith("//")) {
System.out.println();
}
else
System.out.println(lineOfText);
}
scanner.close();
}
}
My task is to read a text file in chunks of 64 characters, and use 2 different processes called Substitution and Column Transposition to encrypt it. Then, I have to decrypt it and write it out to another file.
I have written and tested out both processes of encrypting and decrypting and it worked wonderfully. But then I tried to loop the processes in case more than 64 characters were in the input file.
As a test case, I tried a 128 character input file. Unfortunately, the result only gives me the first 64 characters twice. I've tracked the scanner position and it goes beyond 64, but the characters read start back from 0. I'm not sure what the problem is.
Here is the relevant part of my code:
public static void main(String[] args) {
//Declare variables
Scanner console = new Scanner(System.in);
String inputFileName = null;
File inputFile = null;
Scanner in = null;
do
{
//Check if there are enough arguments
try
{
inputFileName = args[1];
}
catch (IndexOutOfBoundsException exception)
{
System.out.println("Not enough arguments.");
System.exit(1);
}
catch (Exception exception)
{
System.out.println("There was an error. Please try again.");
System.exit(1);
}
//Check if Input File is valid
try
{
inputFile = new File(inputFileName);
in = new Scanner(inputFile);
outputFile = new File(outputFileName);
out = new Scanner(outputFile);
}
catch (FileNotFoundException exception)
{
System.out.println("Could not find input file.");
System.exit(1);
}
catch (Exception exception)
{
System.out.println("There was an error. Please try again.");
System.exit(1);
}
} while (outputFileName != null && !inputFile.exists());
//Encryption
//Prepare patterns
String subPattern = CreateSubstitutionPattern(hash);
int[] transPattern = CreateTranspositionPattern(hash);
//Apply patterns
String textContent = "";
String applySub = "";
String applyTrans = "";
do
{
textContent = Read64Chars(in);
applySub = applySub + ApplySubstitutionPattern(textContent, subPattern);
applyTrans = applyTrans + ApplyTranspositionPattern(applySub, transPattern);
} while (in.hasNext());
//Decryption
String encryptContent = "";
Scanner encrypt = new Scanner(applyTrans);
String removeTrans = "";
String removeSub = "";
do
{
encryptContent = Read64Chars(encrypt);
System.out.println(applyTrans);
removeTrans = removeTrans + RemoveTranspositionPattern(encryptContent, transPattern);
removeSub = removeSub + RemoveSubstitutionPattern(removeTrans, subPattern);
} while (encrypt.hasNext());
console.close();
in.close();
encrypt.close();
System.out.println(removeSub); //For temporary testing
}
public static String Read64Chars (Scanner in)
{
String textContent = "";
in.useDelimiter("");
for (int x=0; x<64; x++)
{
if (in.hasNext())
{
textContent = textContent + in.next().charAt(0);
}
}
return textContent;
}
Do note that I have more variables to fill in args[0] and args[2] but I removed them for simplicity.
I would like to know if it is true that once a scanner reads a portion of it's input, it "consumes" it, and that portion gets removed. Does the scanner reset itself when declared again through a method? For example, does the declaration only point to the input source of the original scanner, or the actual scanner with its current properties?
encrypt is a diffrent Scanner from in, which you advance by 64 characters when you first call Read64Chars. So, encrypt starts at the first character when you call Read64Chars(encrypt). It seems like you want to use the same Scanner both times.
Also, in the future please name your functions starting with a lowercase letter. I felt dirty typing that... :)
A proper solution to get the whole encrypted text would be a code like this
public static String encryptedTextFile (Scanner in)
{
//ArrayList<String> stringBlocksOf64Chars = new ArrayList<String>();
StringBuilder encryptedTxt = new StringBuilder();
String currentTxt = "";
while (in.hasNextLine()) {
String line = currentTxt + in.nextLine();
currentTxt = "";
int i = 0;
for( ; i < line.length()/64 ; i++){
currentTxt = line.substring(i * 64, (i+1)*64);
//TODO - encrypt the text before adding it to the list
encryptedTxt.append(currentTxt);//encryptedTxt.append(encrypt(currentTxt));
}
currentTxt = line.substring(i * 64, line.length());
}
encryptedTxt.append(currentTxt);
/*for(String str : stringBlocksOf64Chars)
System.out.println(str);*/
return encryptedTxt.toString();
}
Your loop for (int x=0; x<64; x++) makes sure that you read only first 64 characters always and not the complete file. To get around that you should actually read whole file line by line.
The above code block follows this idea.
Steps to break down the logic.
Read the file line by line using scanner.
Break each line into chunks of 64 characters and encrypt the block 64 characters at a time
Generate encrypted text adding the encrypted 64 characters.
Whatever you do first break down the logic/steps you want to use in your code to make it simpler to understand or code.
Break the lines into 64 characters
This method is part of a bigger program which asks for specific user input and i need this method to prompt the user for input until its correct. here is what i have
public static String validName(Scanner input, Scanner histogram) {
String user = "";
String name = input.next();
boolean test = false;
while (histogram.hasNext()) {
user = histogram.next();
if (name.equalsIgnoreCase(user)) {
test = true;
break;
}
else {
test = false;
}
}
if (!test) {
System.out.println("Name not found");
}
return user;
}
Scanner histogram is reading a txt file. So far it works fine, but as it is it only goes through once.
What can i change or add to make it work properly?
Here is a quick fix. Create a temporary Scanner and set it equal to histogram before you run through histogram. If the user is found then validName() will return that user, if not then repeat this function by passing in input and the copy of histogram tmp. This will get the job done but is not the right way to go about this task.
Updated
Create a temporary string and add each user to the string followed by a space. If the check fails then recall the function with an anonymous Scanner constructed with the string of users.
public static String validName(Scanner input, Scanner histogram) {
String user = "";
String name = input.next();
String tmp = "";
boolean test = false;
while (histogram.hasNext()) {
user = histogram.next();
tmp += user + " ";
if (name.equalsIgnoreCase(user)) {
test = true;
break;
}
else {
test = false;
}
}
if (!test) {
System.out.println("Name not found");
user = validName(input, new Scanner(tmp));
}
return user;
}
It may not be a perfect solution, but here's how i would do it: first read the complete histogramm into a hash Table. This allows for very efficient input validation later on:
public static String validName(Scanner input, Scanner histogram) {
HashSet<String> validInputs = new HashSet<>();
// read in histogram
while (histogram.hasNext())
validInputs.add(histogram.next());
// ask for input and repeat if necessary
while (true) {
String userInput = input.next();
if (validInputs.contains(userInput))
return userInput;
System.out.println("invalid input");
}
}
i've not tested this solution but it should work.
Also the histogram is only ever read once. After that only the hash values of the different Strings are compared. Since 2 Strings with the same content should always have the same hash value this should work.
Also this solution does not require any recursion.
You can use the Scanner's findInLine(String pattern) method, try the following:
public static String validName(Scanner input, Scanner histogram) {
String user = "";
String name = input.next();
if(histogram.findInLine(name) != null){
System.out.println("This name exist");//Do what you have to do here
}
else{
System.out.println("Name not found");
user = validName(input, histogram);
}
return user;
}
Take a look at the Scanner Class methods for more information.
I'm having difficulty figuring out why this isn't working. Java simply isn't executing the while loop, file apparently does not have a next line.
fileName = getFileName(keyboard);
file = new Scanner (new File (fileName));
pass = true;
String currentLine;
while (file.hasNextLine()) {
currentLine = file.nextLine();
System.out.println(reverse(currentLine));
}
Here is the file I am testing this with. I got it to work with the first few paragraphs but it seems to simply stop working...:
Jabberwocky
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
"Beware the Jabberwock, my son!
The jaws that bite, the claws that catch!
Beware the Jubjub bird, and shun
The frumious Bandersnatch!"
He took his vorpal sword in hand:
Long time the manxome foe he soughtó
So rested he by the Tumtum tree,
And stood awhile in thought.
And as in uffish thought he stood,
The Jabberwock, with eyes of flame,
Came whiffling through the tulgey wood,
And burbled as it came!
One, two! One, two! and through and through
The vorpal blade went snicker-snack!
He left it dead, and with its head
He went galumphing back.
"And hast thou slain the Jabberwock?
Come to my arms, my beamish boy!
O frabjous day! Callooh! Callay!"
He chortled in his joy.
'Twas brillig, and the slithy toves
Did gyre and gimble in the wabe;
All mimsy were the borogoves,
And the mome raths outgrabe.
——from Through the Looking-Glass, and What Alice Found There (1872).
/*
* Lab13a.java
*
* A program that prompts the user for an input file name and, if that file exists,
* displays each line of that file in reverse order.
* Used to practice simple File I/O and breaking code up into methods as well as a first
* step to implementing Lab13b.java - reversing the entire file and Lab13c.java writing
* output to a separate output file.
*
* #author Benjamin Meyer
*
*/
package osu.cse1223;
import java.io.*;
import java.util.*;
public class Lab13a {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String fileName = "";
Scanner file;
boolean pass = false;
while (!pass) {
try {
fileName = getFileName(keyboard);
file = new Scanner (new File (fileName));
pass = true;
String currentLine;
while (file.hasNextLine()) {
currentLine = file.nextLine();
System.out.println(reverse(currentLine));
}
}
catch (FileNotFoundException e) {
System.out.println("There was a problem reading from " + fileName);
System.out.println("Goodbye.");
return;
}
}
}
// Given a Scanner as input prompts the user to enter a file name. If given an
// empty line, respond with an error message until the user enters a non-empty line.
// Return the string to the calling program. Note that this method should NOT try
// to determine whether the file name is an actual file - it should just get a
// valid string from the user.
private static String getFileName(Scanner inScanner) {
boolean pass = true;
String fileName = "";
while (pass) {
System.out.print("Enter an input name: ");
fileName = inScanner.nextLine();
if (fileName.length()!=0) {
pass = false;
}
else {
System.out.println("You cannot enter an empty string.");
}
}
return fileName;
}
// Given a String as input return the reverse of that String to the calling program.
private static String reverse(String inString) {
if (inString.length()==0) {
return "";
}
String reversed = "" + inString.charAt(inString.length()-1);
for (int x = inString.length()-2; x>=0; x--) {
reversed = reversed + inString.charAt(x);
}
return reversed;
}
}
The issue might lie in your implementation of your functions getFilename() or reverse(). Since you have stated that you got it to work with a few of the paragraphs I doubt that your program is failing due to your file handling. It might be in the logic you are using to reverse the strings in the file that is causing the issue.