I'm trying to read a text file for usernames and passwords for a final project. I can get the scanner to read one line, but only one line. I also need to be able to pass the username information along to print a file base on a role contained in the credentials file. Currently, it will only validate the line by line. If I enter the username and password correctly from the first line of the credentials file, it works as expected. If I enter it incorrectly, it will only accept the username and password from the second line of the credentials file.
My question is how do I parse the credentials file properly to search the entire file, not just an individual line.
I do not need to worry about the hash, only the password which is in parenthesis. I also must then print another text file which references the fourth item in each line, but I haven't gotten that far yet.. Any help would be most appreciated.
Text File:
griffin.keyes 108de81c31bf9c622f76876b74e9285f "alphabet soup" zookeeper
rosario.dawson 3e34baa4ee2ff767af8c120a496742b5 "animal doctor" admin
bernie.gorilla a584efafa8f9ea7fe5cf18442f32b07b "secret password" veterinarian
donald.monkey 17b1b7d8a706696ed220bc414f729ad3 "M0nk3y business" zookeeper
jerome.grizzlybear 3adea92111e6307f8f2aae4721e77900 "grizzly1234" veterinarian
bruce.grizzlybear 0d107d09f5bbe40cade3de5c71e9e9b7 "letmein" admin
My code:
public static void main(String[] args)throws FileNotFoundException {
File file = new File ("C:\\Users\\Rick\\Documents\\NetBeansProjects\\IT145finalproject4\\src\\it145finalproject4\\credentials.txt");
String passWord;
String userName;
Scanner scnr = new Scanner (file);
Scanner sc = new Scanner (System.in);
while(scnr.hasNextLine()){
int attempts = 0;
for (int i = 0; i < 3; i++) {
String line = scnr.nextLine();
System.out.println("Enter a username:" );
userName = sc.nextLine();
System.out.println("Enter a password:");
passWord = sc.nextLine();
if(line.contains(userName) && (line.contains (passWord))){
return;
}
if (!line.contains(userName) && (!line.contains (passWord))){
System.out.println("Please try again.");
}
attempts++;
if (attempts == 3){
System.out.println("Maximum attempts reached program exiting.");
}
}
}
}
I believe this amendment fixes the issues you were describing:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestClass
{
public static void main(String[] args) throws FileNotFoundException
{
File file = new File ("C:\\Users\\Mel\\Documents\\test.txt");
String passWord = "";
String userName = "";
Scanner scnr = new Scanner (file);
Scanner sc = new Scanner (System.in);
int attempts = 0, numLines = 0, count = 0;
//Get the number of lines in the file
while(scnr.hasNext())
{
numLines++;
scnr.nextLine();
}
//Reset the scanner
scnr.close();
scnr = new Scanner(file);
while(scnr.hasNextLine())
{
count++;
String line = scnr.nextLine();
//only run this code once per file iteration (at the start)
if (count == 1)
{
System.out.println("Enter a username:" );
userName = sc.nextLine();
System.out.println("Enter a password:");
passWord = sc.nextLine();
}
if(line.contains(userName) && (line.contains (passWord))){
return; //success!
}
//only execute this code once the entire file has been scanned!
if (count == numLines)
{
attempts++;
if (attempts == 3){
System.out.println("Maximum attempts reached program exiting.");
return;
}
if (!line.contains(userName) || (!line.contains (passWord))){
System.out.println("Please try again.");
//reset scanner!
scnr.close();
scnr = new Scanner(file);
count = 0;
}
}
}
}
}
I'm not sure if this is the best solution but I think it is an improvement. Mainly your issue was in not resetting the scanner, but also in calling the input methods too frequently. You will see that the number of lines are initially calculated to help determine when certain code should be called.
I also removed the for loop as it appeared to have no bearing on the code.
Related
I've been doing some exercises from my study book, and I can't seem to figure out this specific one. The instructions are: repeat Exercise P7.2, but allow the user to specify the file name on the command line. If the user does not specify any file name, then prompt the user for the name.
Ín P7.2, which I've completed, we were supposed to write a program that reads a file containing text, read each line and send it to the output file, preceded by line numbers. Basically, what I'm wondering is what I'm supposed to do exactly?
This is my code right now:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter name of file for reading: ");
String fileNameReading = input.next();
System.out.print("Enter name of file for writing: ");
String fileNameWriting = input.next(); om
input.close();
File fileReading = new File(fileNameReading);
Scanner in = null;
File fileWriting = new File(fileNameWriting);
PrintWriter out = null;
try {
in = new Scanner(fileReading);
out = new PrintWriter(fileWriting); fileWriting
} catch (FileNotFoundException e1) {
System.out.println("Files are not found!");
}
int lineNumber = 1;
while (in.hasNextLine()) {
String line = in.nextLine();
out.write(String.format("/* %d */ %s%n", lineNumber, line));
lineNumber++;
}
out.close();
in.close();
System.out.println();
System.out.println("Filen was read and re-written!");
}
I think your exercise just requires a small refactor to use the command line arguments to specify the file for reading:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String fileNameReading;
// check if input file were passed as a parameter
if (args != null && args.length > 0) {
fileNameReading = args[0];
}
// if not, then prompt the user for the input filename
else {
System.out.print("Enter name of file for reading: ");
fileNameReading = input.next();
}
System.out.print("Enter name of file for writing: ");
String fileNameWriting = input.next();
// rest of your code as is
}
You would run your code, for example, as:
java YourClass input.txt
Here we pass in the name of the input file as a parameter.
The same question was asked before but I the help wasn't sufficient enough for me to get it solved. When I run the program many times, it goes well for a string with comma in between(e.g. Washington,DC ). For a string without comma(e.g. Washington DC) the program is expected to print an error message to the screen and prompt the user to enter the correct input again. Yes, it does for the first run. However, on the second and so run, it fails and my suspect is on the while loop.
Console snapshot:
Enter input string:
Washington DC =>first time entered & printed the following two lines
Error: No comma in string.
Enter input string:
Washington DC => second time, no printouts following i.e failed
Here's my attempt seeking your help.
public class practice {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
String userInput = "";
String delimit =",";
boolean inputString = false;
System.out.println("Enter input string:");
userInput = scnr.nextLine();
while (!inputString) {
if (userInput.contains(delimit)){
String[] userArray = userInput.split(delimit);
// for(int i=0; i<userArray.length-1; i++){
System.out.println("First word: " + userArray[0]); //space
System.out.println("Second word:" + userArray[1]);
System.out.println();
//}
}
else if (!userInput.contains(delimit)){
System.out.println("Error: No comma in string.");
inputString= true;
}
System.out.println("Enter input string:");
userInput = scnr.nextLine();
while(inputString);
}
}
}
You can easily solve this problem using a simple regex ^[A-Z][A-Za-z]+, [A-Z][A-Za-z]+$
So you can check the input using :
boolean check = str.matches("^[A-Z][A-Za-z]+, [A-Z][A-Za-z]+$");
Then you can use do{}while() loop instead, so your code should look like this :
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
String userInput;
do {
System.out.println("Enter input string:");
userInput = scnr.nextLine();
} while (!userInput.matches("^[A-Z][A-Za-z]+, [A-Z][A-Za-z]+$"));
}
regex demo
Solution 2
...But I can't apply regex at this time and I wish others help me to
finish up the work the way I set it up
In this case you can use do{}while(); like this :
Scanner scnr = new Scanner(System.in);
String userInput;
String delimit = ",";
boolean inputString = false;
do {
System.out.println("Enter input string:");
userInput = scnr.nextLine();
if (userInput.contains(delimit)) {
String[] userArray = userInput.split(delimit);
System.out.println("First word: " + userArray[0]);
System.out.println("Second word:" + userArray[1]);
System.out.println();
} else if (!userInput.contains(delimit)) {
System.out.println("Error: No comma in string.");
inputString = true;
}
} while (inputString);
I am attempting to write a program that will take user input ( a long message of characters), store the message and search a text file to see if those words occur in the text file. The problem I am having is that I am only ever able to read in the first string of the message and compare it to the text file. For instance if I type in "learning"; a word in the text file, I will get a result showing that is is found in the file. However if I type "learning is" It will still only return learning as a word found in the file even though "is" is also a word in the text file. My program seems to not be able to read past the blank space. So I suppose my questions is, how do I augment my program to do this and read every word in the file? Would it also be possible for my program to read every word, with or without spaces, in the original message taken from the user, and compare that to the text file?
Thank you
import java.io.*;
import java.util.Scanner;
public class Affine_English2
{
public static void main(String[] args) throws IOException
{
String message = "";
String name = "";
Scanner input = new Scanner(System.in);
Scanner scan = new Scanner(System.in);
System.out.println("Please enter in a message: ");
message = scan.next();
Scanner file = new Scanner(new File("example.txt"));
while(file.hasNextLine())
{
String line = file.nextLine();
for(int i = 0; i < message.length(); i++)
{
if(line.indexOf(message) != -1)
{
System.out.println(message + " is an English word ");
break;
}
}
}
}
}
I recommend you first process the file and build a set of legal English words:
public static void main(String[] args) throws IOException {
Set<String> legalEnglishWords = new HashSet<String>();
Scanner file = new Scanner(new File("example.txt"));
while (file.hasNextLine()) {
String line = file.nextLine();
for (String word : line.split(" ")) {
legalEnglishWords.add(word);
}
}
file.close();
Next, get input from the user:
Scanner input = new Scanner(System.in);
System.out.println("Please enter in a message: ");
String message = input.nextLine();
input.close();
Finally, split the user's input to tokens and check each one if it is a legal word:
for (String userToken : message.split(" ")) {
if (legalEnglishWords.contains(userToken)) {
System.out.println(userToken + " is an English word ");
}
}
}
}
You may try with this. With this solution you can find each word entered by the user in your example.txt file:
public static void main(String[] args) throws IOException
{
String message = "";
String name = "";
Scanner input = new Scanner(System.in);
Scanner scan = new Scanner(System.in);
System.out.println("Please enter in a message: ");
message = scan.nextLine();
Scanner file = new Scanner(new File("example.txt"));
while (file.hasNextLine())
{
String line = file.nextLine();
for (String word : message.split(" "))
{
if (line.contains(word))
{
System.out.println(word + " is an English word ");
}
}
}
}
As Mark pointed out in the comment, change
scan.next();
To:
scan.nextLine();
should work, i tried and works for me.
If you can use Java 8 and Streams API
public static void main(String[] args) throws Exception{ // You need to handle this exception
String message = "";
Scanner input = new Scanner(System.in);
System.out.println("Please enter in a message: ");
message = input.nextLine();
List<String> messageParts = Arrays.stream(message.split(" ")).collect(Collectors.toList());
BufferedReader reader = new BufferedReader(new FileReader("example.txt"));
reader.lines()
.filter( line -> !messageParts.contains(line))
.forEach(System.out::println);
}
You have many solution, but when it comes to find matches I suggest you to take a look to the Pattern and Matcher and use Regular Expression
I haven't fully understood your question, but you could do add something like this (I did not tested the code but the idea should work fine):
public static void main(String[] args) throws IOException{
String message = "";
String name = "";
Scanner input = new Scanner(System.in);
Scanner scan = new Scanner(System.in);
System.out.println("Please enter in a message: ");
message = scan.next();
Scanner file = new Scanner(new File("example.txt"));
String pattern = "";
for(String word : input.split(" ")){
pattern += "(\\b" + word + "\\b)";
}
Pattern r = Pattern.compile(pattern);
while(file.hasNextLine())
{
String line = file.nextLine();
Matcher m = r.matcher(line);
if(m.matches()) {
System.out.println("Word found in: " + line);
}
}
}
I wrote a program to keep a user out unless they know the username and password. It's just a program I wrote for fun, and it doesn't really have a purpose. However, while testing the code I noticed an issue when trying to read from a file that was recently written to. For whatever reason the scanner object I created for the username.txt file, userOut, doesn't detect their is anything in the file (i.e. .hasNextLine() returns false), but only if it was written to within the program. If I write some text to the file, then run the program, it works just fine. Please note that the password.txt file works completely fine. Why is this happening?
Here's my code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Scanner;
public class Challenge5 {
public static void main(String[] args) {
try {
File usernameFile = new File("username.txt");
File passwordFile = new File("password.txt");
PrintWriter userOut = new PrintWriter(new FileOutputStream(usernameFile, true));
PrintWriter passOut = new PrintWriter(new FileOutputStream(passwordFile, true));
Scanner in = new Scanner(System.in);
Scanner userIn = new Scanner(usernameFile, "UTF-8");
Scanner passIn = new Scanner(passwordFile, "UTF-8");
System.out.println("Welcome to Luke's secure program.");
if (!userIn.hasNextLine() || !userIn.hasNextLine()) {
System.out.println("New users must set up their account: ");
if (!userIn.hasNextLine()) {
System.out.print("Enter a username: ");
String username = in.nextLine().trim();
userOut.print(username);
userOut.flush();
}
if (!userIn.hasNextLine()) {
System.out.print("Enter a password: ");
String password = in.nextLine().trim();
passOut.print(password);
passOut.flush();
}
System.out.println("Your account has been created. You may now log in:");
}
System.out.print("Please enter username: ");
String username = in.nextLine().trim();
System.out.print("Please enter password: ");
String password = in.nextLine().trim();
String fileUsername = "";
while (userIn.hasNextLine()) {
fileUsername = userIn.nextLine();
}
System.out.println(fileUsername);
String filePassword = "";
while (passIn.hasNextLine()) {
filePassword = passIn.nextLine();
}
System.out.println(filePassword);
if (username.equals(fileUsername) && password.equals(filePassword)) {
System.out.println("Welcome!");
while (true) {
System.out.println("What would you like to do? ");
System.out.println("1. Change username\n2. Change password\n3. Exit");
System.out.print("> ");
int choice;
while (!in.hasNextInt()) {
System.out.println("What would you like to do? ");
System.out.println("1. Change username\n2. Change password\n3. Exit");
System.out.print("> ");
in.next();
}
choice = in.nextInt();
in.nextLine();
if (choice == 1) {
userOut = new PrintWriter(new FileOutputStream(usernameFile, false));
System.out.print("Enter new username: ");
String newUsername = in.nextLine().trim();
userOut.print(newUsername);
userOut.flush();
} else if (choice == 2) {
passOut = new PrintWriter(new FileOutputStream(passwordFile, false));;
System.out.print("Enter new password: ");
String newPassword = in.nextLine().trim();
passOut.print(newPassword);
passOut.flush();
} else if (choice == 3) {
System.out.println("Goodbye!");
break;
} else {
System.out.println("Please try again.");
}
}
} else {
System.out.println("INVALID USERNAME OR PASSWORD, EXITING PROGRAM...");
}
userOut.close();
passOut.close();
in.close();
userIn.close();
passIn.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
I recognize my code isn't perfect, but I think it should at the very least work. Any help would be appreciated.
You need to reinitialize your Scanner objects to open input stream to the updated files content.
System.out.print("Please enter password: ");
String password = in.nextLine().trim();
Just after above two lines, you need the following:
userIn = new Scanner(usernameFile, "UTF-8");
passIn = new Scanner(passwordFile, "UTF-8");
The reason you fail to read nothing is because you open input stream connection to file username and password using userIn and passIn when there is nothing in file. Adding the above two lines open new input stream connection to the updated file hence, you will be able to read the content.
You seem to be having a bit of issue with your conditions below:
//if (!userIn.hasNextLine() || !userIn.hasNextLine()) {
if (!userIn.hasNextLine() || !passIn.hasNextLine()) {
System.out.println("New users must set up their account: ");
if (!userIn.hasNextLine()) {
System.out.print("Enter a username: ");
String username = in.nextLine().trim();
userOut.print(username);
userOut.flush();
}
//why again !userIn.hasNextLine(), you should check passIn
//if (!userIn.hasNextLine()) {
if (!passIn.hasNextLine()) {
System.out.print("Enter a password: ");
String password = in.nextLine().trim();
passOut.print(password);
passOut.flush();
}
System.out.println("Your account has been created. You may now log in:");
}
I have fixed the two conditions and commented out your code bit.
hi I have this Java code,
import java.io.*;
import java.util.*;
public class SongWriter
{
public static void main(String[] args)
{
PrintWriter outputStream = null; // Scope must be outside the try/catch structure
try
{
outputStream = new PrintWriter("Song.txt"); // new
FileOutputStream("Song.txt")
}
catch(FileNotFoundException e)
{
System.out.println("Error opening the file Song.txt.");
System.exit(0);
}
System.out.println("\n classical songs has many lines");
System.out.println("\nNow enter the three lines of your Song.");
String line = null;
Scanner keyboard = new Scanner(System.in);
int count;
for (count = 1; count <= 3; count++)
{
System.out.println("\nEnter line " + count + ": ");
line = keyboard.nextLine();
outputStream.println(count + "\t" + line);
}
outputStream.close();
System.out.println("\nYour Song has been written to the file Song.txt.\n");
} // end of main
} // end of class
how do I Adjust the program so it first asks for a name of the file to write to. Use the Scanner class and its next() method. Read in the file name as a string variable after informing the reader the file name should end in the suffix .txt
Eg:- Song with the file names Haiku1.txt, Haiku2.txt and Haiku3.txt.
You almost had it.
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter first file name:");
String first = keyboard.nextLine();
System.out.println("Enter second file name:");
String second = keyboard.nextLine();
System.out.println("Enter third file name:");
String third = keyboard.nextLine();
//and so on and continue whatever you want to do..
EDIT: After your comment.
First store the 3 lines in a StringBuilder and then ask for the file name to write. Now you have the lyrics and file name.
Using the Scanner class to get input from the user:
String fileName1;
Scanner keyboard = new Scanner(System.in); //creates Scanner object
System.out.print ("Enter the name of the file. The file should end in the suffix .txt") //prompt the user to enter the file name
fileName1 = keyboard.next(); //store the name of the file
You should do this before the try/catch block so that you can use the filename that the user entered instead hardcoding it (like you did here with song.txt).
You can prompt the user this way for as many file names as you need.