I have 3 different classes. I have to get user input by using BufferedReader but by using toString method. Below is the codes in my User2 (one of the classes).
How to call everything that user have input in the toString, at main function ? if i have to use object, how?
//in User2 class
#Override
public String toString() {
try {
//getting input using BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter customer name: ");
this.name = br.readLine();
System.out.print("Enter customer address: ");
this.address = br.readLine();
System.out.print("Enter customer contact no: ");
this.hp = br.readLine();
} catch (IOException e) {
return "";
}
return "" ;
}
I only know to print out everything in to string by using
System.out.println(u2.toString());
Thanks in advance.
You shouldn't be defining an Object when you call it's toString() method, especially when you are using Scanner to read data from System.in. Rather, when you read data you should use the data to instantiate the Object. I haven't seen the layout of your classes, but I have a feeling you don't fully understand what Objects are.
The following Class defines a User; The user has a name, address and hp. You create a new User Object once you have this information as, in this situation, it doesn't make sense to have an Object that doesn't represent a known User.
The toString() method has been overriden such that it produces a String that is representative of what the Object describes - You should adjust this to how you want the Object to be representative when the Object to converted to a String. Read more about the toString method and it's purpose.
The static User userFromInput() method does what you want. As it is static, you may invoke it on the Class, meaning you don't have to instantiate an Object. This method takes input from the user (name, address and hp), instantiates a new User object and returns it.
public class User {
private String name;
private String address;
private String hp;
public User (String name, String address, String hp) {
this.name = name;
this.address = address;
this.hp = hp;
}
#Override
public String toString() {
return name + " : " + address + " : " + hp;
}
public static User userFromInput() {
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
System.out.print("Enter customer name: ");
String name = br.readLine();
System.out.print("Enter customer address: ");
String address = br.readLine();
System.out.print("Enter customer contact no: ");
String hp = br.readLine();
return new User(name, address, hp);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Hence, you should call for the user to input data and then print the Object to console using the following to lines:
User user1 = User.userFromInput();
System.out.println(user1.toString());
Related
I have few same type text files.
name: Michel;
race: Man;
age: 44;
How to parse them values to List Characters
public class Character {
private String name;
private String race;
private String age;
}
You can use a BufferedReader, FileReader or Scanner object to read txt files in Java. It depends on which you'd like to use for it's functions.
You can use them to iterate trough lines in the txt file and you can put that read content in a String. Then you can assign that stringvalue to your objectvariables.
A quick google brought me to this website which explains the methods complete with code examples: https://www.geeksforgeeks.org/different-ways-reading-text-file-java/
Here add one character with change name class
List<Person> personList = new ArrayList<>();
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(String.valueOf(path))));
String line;
String name = null;
String race = null;
String age = null;
while ((line = br.readLine()) != null) {
if (line.contains("name:")) {
name = line.substring(6, line.length() - 1);
}
if (line.contains("race:")) {
race = line.substring(6, line.length() - 1);
}
if (line.contains("age:")) {
age = line.substring(5, line.length() - 1);
}
}
Person person = new Person();
person.setName(name);
person.setRace(race);
person.setAge(age);
personList.add(person);
return personList;
I'm creating a menu based console application using Java. I have a class that allows the user to sign up by inputting their information. This information is written to a file that is appended each time a new user is entered.
I would like to have a login function, but I'm having trouble figuring out how to read the file and only match the user input to the first two columns ID;Password.
Once they match the user input, I'll be able to continue to the next menu.
My text file looks like this:
ID;Password;FirstName;LastName;Email
admin;1234;adminFirst;adminLast;adminMail#admin.com
Here's my Login class as well. I created an array for user input, just in case that would be useful:
public class Log_In extends Main_Menu {
public void logging_in(){
Scanner in = new Scanner(System.in);
System.out.println("Please enter your login information!");
String [] log_in_array = new String[2];
String ID, password;
System.out.print("ID: ");
ID = in.next();
System.out.print("Password: ");
password = in.next();
//Stores the ID and PASSWORD to the array. Now we will compare the array to the txt file to find a match
//Must match FIELD_ONE;FIELD_TWO
log_in_array [0] = ID;
log_in_array [1] = password;
in.close();
}
}
you can write helper method to read your text file and compare id and password provided by user, like following.
// The name of the file to open.
static String fileName = "myTextFliel.txt";
public static boolean myHelper(String id, String password) {
// This will reference one line at a time
String line = null;
boolean retVal= false;
try {
// FileReader reads text files in the default encoding.
FileReader fileReader =
new FileReader(fileName);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader =
new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null) {
//create a token based on
String [] token=line.split(";");
// because you know first and second word of each line in
// given file is id and password
if (token[0].equals(id) && token[1].equals(password)){
retVal=true;
return retVal;
}
}
// Always close files.
bufferedReader.close();
}
catch(FileNotFoundException ex) {
System.out.println(
"Unable to open file '" +
fileName + "'");
}
catch(IOException ex) {
System.out.println(
"Error reading file '"
+ fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
}
return retVal;
}
public void logging_in(){
Scanner in = new Scanner(System.in);
System.out.println("Please enter your login information!");
String [] log_in_array = new String[2];
String ID, password;
System.out.print("ID: ");
ID = in.next();
System.out.print("Password: ");
password = in.next();
//Stores the ID and PASSWORD to the array. Now we will compare the array to the txt file to find a match
//Must match FIELD_ONE;FIELD_TWO
log_in_array [0] = ID;
log_in_array [1] = password;
// Here you can call your helper method.
boolean foundMe =myHelper(log_in_array [0],log_in_array [1])
if (foundMe==true){
//do whatever u want to do
}
in.close();
}
With little bit of more work you can ignore header line.
If the structure of the file is something like this
username pass data data
username pass data data
username pass data data... and so on
you can read the file into an ArrayList, but skip everything that isn't a user name or pass like so
ArrayList<String> userinfo = new ArrayList();
while (input.hasNext()){ //input is a Scanner object that is your file
userinfo.add(input.next());//username
userinfo.add(input.next());//pass
input.next();//skip
input.next();//skip
}
every username and password will be in pairs like this within the
ArrayList
(username, pass, username, pass, username, pass,...)
Then to see if a username and password matches
int index = userinfo.indexOf(ID);
if (userinfo.get(index+1).equals(password))//the password comes right after the username in the list
return true;
I'm assuming this is for practice, you would typically use a database of some sort for user name and passwords
I have variables that are from my main, and I want to use a private (or public doesn't really matter I am keeping them in the same class) method to write them to a text file. I have accomplished writing them to a file from within the main... I just cant figure out how to call variables from the main into my writeToFile() method. Below is what I have attempted but Im not sure how to incorporate the two.
//This portion is what I had in my main method that wrote the info to a file successfully
//Write to File
String fileName = "order.txt";
try{
PrintWriter writer = new PrintWriter(fileName);
writer.println("Thank you for ordering from Diamond Cards");
writer.println("Name: " + customerName);
writer.println("Returning Customer: " + customerReturn );
writer.println("Phone: " + custNumber);
writer.println("Card Type: " + customerType);
writer.println("Card Color: " + customerColor);
writer.println("Card Coating: " + customerCoat);
writer.println("Item Amount: " + numItems);
writer.println("Total Cost: " + fmt1.format(totalCostMsg));
writer.flush();
writer.close();
JOptionPane.showMessageDialog(null, "Receipt has been printed");
} catch (FileNotFoundException e)
{e.printStackTrace();
System.exit(0) ;
}
}
// This is where I try to create a method to do the file writing.... not sure how to proceed..
public static void writeToFile() {
try{
FileWriter fw = new FileWriter("order.text"); //File name to be created
PrintWriter pw = new PrintWriter (fw); // Prints to the file that was created
//text to be printed to file
// close the writer
pw.close();
// catch errors
} catch (IOException e) {
out.println("Error!");
}
}
I also need to figure out how to make a separate method to read the file back in but I think I can engineer that if I can just figure this part out.
You can pass objects around by adding parameters to your methods. If you need to reference something in another class or method, just add more parameters.
I suggest that you create a Customer object so that you can pass it around as a single entity instead a couple dozen parameters.
You can try something like this:
public class FileWriteExample {
public static void main(String[] args) {
String fileName = "order.txt";
Customer customer; // Customer object...
int itemCount;
float totalCost;
try {
PrintWriter writer = new PrintWriter(fileName);
writeToFile(writer, customer, itemCount, totalCost);
writer.flush();
writer.close();
JOptionPane.showMessageDialog(null, "Receipt has been printed");
} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(0);
}
}
public static void writeToFile(PrintWriter writer, Customer customer,
int itemCount, float totalCost) {
Card card = customer.getCard();
try {
writer.println("Thank you for ordering from Diamond Cards");
writer.println("Name: " + customer.getName());
writer.println("Returning Customer: " + customer.getReturn());
writer.println("Phone: " + customer.getPhone());
writer.println("Card Type: " + card.getType());
writer.println("Card Color: " + card.getColor());
writer.println("Card Coating: " + card.getCoating());
writer.println("Item Amount: " + itemCount);
writer.println("Total Cost: " + fmt1.format(totalCost));
} catch (IOException e) {
System.out.println("Error!");
}
}
}
You want to define writeToFile with arguments, and pass them in from main:
// Add additional arguments.
public static void writeToFile(String fileName, String customerName, ...){
FileWriter fw = new FileWriter(fileName);
writer.println("Thank you for ordering from Diamond Cards");
writer.println("Name: " + customerName);
// Use additional arguments.
}
From main:
writeToFile(fileName, customerName, ...);
I agree with Mr. Polywhirl though. It will be cleaner if you create a wrapping object, although I am not so sure you even need getters and setters for this purpose.
// The types are all String because you did not mention the types in your
// question.
class Customer {
public String Name;
public String Return;
public String Number;
public String Type;
public String Color;
public String Coat;
public Customer String(String Name, String Return, String Number, String Type, String Color, String Coat) {
this.Name = Name;
this.Return = Return;
this.Number = Number;
this.Type = Type;
this.Color = Color;
this.Coat = Coat;
}
}
You could then do the following in main:
Customer c = new Customer(customerName, customerReturn, customerNumber, customerType, customerColor, customerCoat);
Inside the writeToFile method with the same signature as Mr. Polywhirl's answer, you could directly do customer.Name, etc.
There might be some fields that are not required or unavailable, like contact number, etc. Rather than sending a long list to write to file, consider using a Builder Pattern as suggested by Joshua Bloch in Effective Java.
I have some code that reads from a csv file that is full of the last name, first name, and birth year of a lot of people. It looks like this in the csv file:
nameLast nameFirst birthYear
Santos Valerio 1972
Tekulve Kent 1947
Valentine Fred 1935
I have a class called Human, and the human class also has these three values. I would like to create an array of the human class, and pass into it all of my data from the csv file. That way, if the first instance of the array at [0] will have three values in it, two for the names and one for the year. Here is the code I have so far:
package testing.csv.files;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Human {
String lastName;
String firstName;
String birthYear;
public static void main(String[] args) {
//.csv comma separated values
String fileName = "C:/Users/Owner/Desktop/Data.csv";
File file = new File(fileName); // TODO: read about File Names
try {
Scanner inputStream = new Scanner(file);
inputStream.next(); //Ignore first line of titles
while (inputStream.hasNext()){
String data = inputStream.next(); // gets a whole line
String[] values = data.split(",");
System.out.println(values[2]);
}
inputStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
What I have here will currently print out all of the birth years, since values[2] is the birth year. I thought that I could change the line
String[] values = data.split(",");
To read
Human[] values = data.split(",");
And then it would automatically assign the values lastName, firstName, and birthyear into the right places for every object in the array. However, doing this just produces the error message
incompatible types: String[] cannot be converted to Human[]
I tried also changing the line above this one from
String data = inputStream.next(); // gets a whole line
to
Human data = inputStream.next(); // gets a whole line
but I get the same error message.
So what am I doing wrong? Perhaps I didn't properly define the class as I thought I did, or is there something much more wrong with my approach? Please let me know what you think.
First of all, your Human class needs a constructor. Insert the following method.
public Human(String[] str) {
lastName = str[0];
firstName = str[1];
birthYear = str[2];
}
Now, instead of a string array, you can get a Human object using
Human someHuman = new Human(data.split(","));
The method split in class String returns an array of Strings, not an array of Human. To create an array of Human, you'll need to parse that String array returned from split into the values human needs.
class Human{
String firstName;
String lastName;
int birthYear;
public Human(String first, String last, int birthYear){
this.firstName = first;
this.lastName = last;
this.birthYear = birthYear;
}
}
int numHumansInCSV = //How many humans are in your file?
Human[] humanArray = new Human[numHumansInCSV];
int index = 0;
while (inputStream.hasNext()){
String data = inputStream.next(); // gets a whole line
String[] values = data.split(",");
String lastName = values[0];
String firstName = values[1];
int birthYear = Integer.parseInt(values[2]);
Human human = new Human(firstName, lastName, birthYear);
//put human in human array.
humanArray[index] = human;
index += 1;
}
If you can use a datastructure like List, that'd be more appropriate than an array as you might not know how many humans your CSV file contains.
Also, this parsing code should really be in its own class. If I were writing this, here's what I'd do.
public class HumanCSVReader{
public List<Human> read(String csvFile, boolean expectHeader) throws IOException{
File file = new File(csvFile);
Scanner scanner = new Scanner(file);
int lineNumber = 0;
List<Human> humans = new List<Human>();
while(scanner.hasNextLine()){
if(expectHeader && lineNumber==0){
++lineNumber;
continue;
}
String line = scanner.nextLine();
String csv = line.split(",");
if(csv.length!=3)
throw new IOException("Bad input in "+csvFile+", line "+lineNumber);
String firstName = list[0];
String lastName = list[1];
try{
int birthYear = Integer.parseInt(list[2]);
}catch(NumberFormatException e){
throw new IOException("Bad birth year in "+csvFile+", line "+lineNumber);
}
Human human = new Human(fistName, lastName, birthYear);
humans.add(human);
++lineNumber;
}
return humans;
}
}
Just use this to load in your array of humans instead. It'll even handle some basic validation.
This is a workout program which asks the user for his name and creates a file where all his data is stored. Inside that file, there are 3 literals: fullName, age and experience.
The feature which is not working is printing out all the information inside the file, when the user enters his username.
So, if I had an account called Bob, and I entered Bob in the console, I should get my fullName, my Age and my experience. (which had already been stored in the file before).
This is my method for reading data from the file and printing it out. I ran it several times with the debugger but it only reads the title of the file and not the information inside it. The result is "Could not find file". How do I fix this? Thanks.
public void getInfo(String nameIn) {
Scanner keyboard = new Scanner(System.in);
Scanner x;
out.println("\nWhat's your account's name?");
nameIn = keyboard.nextLine();
//It reads the title of the file, not the data inside it.
try {
x = new Scanner(nameIn);
if (x.hasNext()) {
String a = x.next();
String b = x.next();
String c = x.next();
out.println("Account data for user: " + nameIn);
out.printf("Name: %s \tAge: %s \tExperience: %s", a, b, c);
}
} catch (Exception e) {
out.println("Could not find file.");
}
Here's the rest of the code in that class.
public class createMember {
public String name;
private String fullName;
private String age;
private String experience;
private Formatter x;
public createMember(String name) {
this.name = name;
}
public void setMembership() {
try {
x = new Formatter(name);
out.println("File with name \"" + name + "\" has been created!");
} catch (Exception e) {
out.println("Could not create username.");
}
}
public void setInfo() {
Scanner keyboard = new Scanner(System.in);
out.println("Enter your Full Name");
fullName = keyboard.nextLine();
out.println("Enter your Age");
age = keyboard.nextLine();
out.println("Enter your lifting experience");
experience = keyboard.nextLine();
x.format("Name: %s \tAge: %s \tExperience: %s", fullName, age, experience);
}
public void getInfo(String nameIn) {
Scanner keyboard = new Scanner(System.in);
Scanner x;
System.out.println("\nWhat's your account's name?");
nameIn = keyboard.nextLine();
//It reads the title of the file, not the data inside it.
try {
File file = new File("nameOfYourFile.txt");
x = new Scanner(file);
while (x.hasNextLine())) {
String line = x.nextLine();
if (line.contains(nameIn)){ // or you can use startsWith()
// depending how your text is formatted
String[] tokens = line.split(" ");
String a = tokens[0].trim();
String b = tokens[1].trim();
String c = tokens[2].trim();
System.out.println("Account data for user: " + nameIn);
System.out.printf("Name: %s \tAge: %s \tExperience: %s", a, b, c);
}
}
} catch (FileNotFoundException e) {
System.out.println("Could not find file.");
}
You have to pass an InputStream to your scanner, not the name of the file.
final String pathToFile = "/my/dir/" + nameIn;
x = new Scanner(new FileInputStream(new File(pathToFile)));
Even though I must say I have never seen this approach to read a file line by line. I usually do this using a BufferedLineReader.
Checking hasNext() once and invoking next() thrice is not a good design. Any of the next() calls after the first might fail if no more tokens are available.
So, one possibility is that you're running out of tokens after the first x.next() call.
Another possibility is that the given pathname nameIn does not correspond to any file on the file system.
Also, you should be catching exception using more specific types instead of Exception. If you had done that, you would have known which of the new Scanner(file) or x.next() threw exception.