I remember doing something identical in Python and finding it easy, but I can't seem to find a solution in Java. I basically need to program to read a text file, but only the first part of each line.
The text file currently looks like
test1,Test1
test2,Test2
test3,Test3
I have a validation system so when a user signs up, it checks the username is not already taken. I just need to be able to check the usernames without the passwords, or in other words, read the line up to the comma. I already have the code to check the username and password for the login, which looks like this
String user = userText.getText();
String pString = String.valueOf(passwordText.getPassword());
File file = new File("C:/Users/Will/Desktop/UnPs.txt");
boolean found = false;
Scanner scan = null;
try {
scan = new Scanner(file);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(scan.hasNextLine() && found == false) {
String passCheck = scan.nextLine();
if(passCheck.equals(user + "," + pString)) {
System.out.println("Found");
found = true;
}
else if(!passCheck.equals(user + "," + pString)) {
System.out.println("not found");
}
}
I'm sure this has been asked before, but I can't seem to find anything related to the subject.
As I understand it, you can do something like this
Scanner read = new Scanner (new File("C:/Users/Will/Desktop/UnPs.txt"));
read.useDelimiter(",");
String name, pwd;
while(read.hasNext())
{
name = read.next();
pwd= read.next();
System.out.println(name+ " " + pwd + "\n"); //just for debugging
}
read.close();
Or use split method : https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#split(java.lang.String)
maybe too simple, but try
...
String nameCheck = scan.nextLine();
if (nameCheck.startsWith(userName + ",")) {
...
to really get the name of each line:
...
String line = scan.nextLine();
int comma = line.indexOf(',');
if (comma != -1) {
String name = line.substring(0, comma);
...
} else {
//no comma? error message, or just ignore
}
or using regular expression :
...
String line = scan.nextLine();
String name = line.replaceFirst(",.*", "");
...
despite I think that regular expression is kind of an overkill here...but neat
Related
I'm creating a program, where i must read special text files. I have a problem with a reading text from specified word to another specified word(not including these words). Is using a scanner a good approach to this problem?
I mean something like that:
"text1
text2
text3
text4
text5"
And i want to get from it String with "text2 text3 text4".
I tried using useDelimeter but I can not figure out how to apply it to this case. I created a method that allows me to skip lines, but this is not a good solution in the long run and it will work for only one specified file.
Here is one of my methods I want to make it here
private String readFile3(File file) {
try {
Scanner sc = new Scanner(file);
//skipLine(sc, 8);
sc.useDelimiter("R");
String sentence = sc.next();
textAreaD.setText(sentence);
} catch (FileNotFoundException e) {
System.out.println("No file");
}
return null;
}
How about something like this:
private String readFile3(File file) {
try {
Scanner sc = new Scanner(file);
boolean save = false;
String sentence = "";
String temp = "";
while (sc.hasNextLine()) {
temp = sc.nextLine();
if (sentence.contains("text1")) {
if (!save) {
temp = sc.nextLine();
}
save = true;
}
if (sentence.contains("text5")) {
save = false;
}
if (save) {
sentence = sentence + temp;
}
}
// skipLine(sc, 8);
//sc.useDelimiter("R");
sentence = sentence.replaceAll("\\n", "");
textAreaD.setText(sentence);
} catch (FileNotFoundException e) {
System.out.println("No file");
}
return null;
}
Should read out all strings between "text1" and "text5". Maybe you have to do some more formatting and check if "text1" occurs more than one time, if you want to save that too, but i hope it helps you.
I want to send studentGrade array to "calculate" method to calculate the average of grades but if the first line of text file is parameter, I can't. When the "if" method running, it goes back to while loop, even though two strings are equal.
I've tried to change the first line of .txt, in case of there is a problem. But the result was the same. It never does compare if the wanted person is in the first line.
static int studentNumber = 0;
static String[] studentGrade;
static String studentName = "";
static void makeList(String name) {
try(Scanner sc = new Scanner(new BufferedReader(new FileReader("C:\\Users\\User\\Desktop\\new_1.txt")))) {
boolean flag = true;
while (sc.hasNextLine()) {
flag = true;
String studentLine = sc.nextLine();
studentGrade = studentLine.split(",");
studentName = studentGrade[0];
if (studentName.equalsIgnoreCase(name)){
calculate(studentGrade);
flag = false;
break;
}
}
if (flag)
System.out.println("Couldn't found!");
}
catch (FileNotFoundException e) {
System.out.println("An error occured when the file was tried to opened.");
}
}
static void calculate(String[] a) {
int note1 = Integer.parseInt(a[1]);
int note2 = Integer.parseInt(a[2]);
int note3 = Integer.parseInt(a[3]);
double avg = Math.ceil((double)(note1 + note2 + note3) / 3);
System.out.println(a[0] + "'s average is: " + (int)avg);
}
I expect the if case would be true and sent the array to "calculate" method. It does its job except the student is in the first line of .txt file. For example if user input is Michael, it says "Couldn't found!" but if the input is John, it gives its average.
//First lines of .txt file
Michael,70,90,20
John,90,80,60
Molly,60,30,50
I created a file with the values you are giving:
Michael,70,90,20
John,90,80,60
Molly,60,30,50
And when I try your code, it seems to work fine:
makeList("Michael");
makeList("John");
makeList("Molly");
return
60
77
47
My suspicion is that you have some kind of invisible character at the very beginning of your file, and that is what makes your equality fail. I encountered this kind of issue several time when parsing XML and the parser would complain that my file doesn't start with an XML tag.
Can you try to make a brand new file with these 3 lines and try your program again on this new file?
Here is a much simpler and clearer way to do this:
try (Stream<String> lines = Files.lines("C:\\Users\\User\\Desktop\\new_1.txt")) {
Optional<String[]> studentGradesOpt =
lines.map(line -> line.split(","))
.filter(row -> row[0].equalsIgnoreCase(name))
.findFirst();
studentGradesOpt.ifPresent(grades -> calculate(grades));
if (!studentGradesOpt.isPresent()) {
System.out.println("Couldn't find student " + name);
}
}
I have a text file named "message.txt" which is read using Buffer Reader. Each line of the text file contains both "word" and "meaning" as given in this example:
"PS:Primary school"
where PS - word, Primary school - meaning
When the file is being read, each line is tokenized to "word" and "meaning" from ":".
If the "meaning" is equal to the given input string called "f_msg3", "f_msg3" is displayed on the text view called "txtView". Otherwise, it displays "f_msg" on the text view.
But the "if condition" is not working properly in this code. For example if "f_msg3" is equal to "Primary school", the output on the text view must be "Primary school". But it gives the output as "f_msg" but not "f_msg3". ("f_msg3" does not contain any unnecessary strings.)
Can someone explain where I have gone wrong?
try {
BufferedReader file = new BufferedReader(new InputStreamReader(getAssets().open("message.txt")));
String line = "";
while ((line = file.readLine()) != null) {
try {
/*separate the line into two strings at the ":" */
StringTokenizer tokens = new StringTokenizer(line, ":");
String word = tokens.nextToken();
String meaning = tokens.nextToken();
/*compare the given input with the meaning of the read line */
if(meaning.equalsIgnoreCase(f_msg3)) {
txtView.setText(f_msg3);
} else {
txtView.setText(f_msg);
}
} catch (Exception e) {
txtView.setText("Cannot break");
}
}
} catch (IOException e) {
txtView.setText("File not found");
}
Try this
............
meaning = meaning.replaceAll("\\s+", " ");
/*compare the given input with the meaning of the read line */
if(meaning.equalsIgnoreCase(f_msg3)) {
txtView.setText(f_msg3);
} else {
txtView.setText(f_msg);
}
............
Otherwise comment the else part, then it will work.
I don't see any obvious error in your code, maybe it is just a matter
of cleaning the string (i.e. removing heading and trailing spaces, newlines and so on) before comparing it.
Try trimming meaning, e.g. like this :
...
String meaning = tokens.nextToken();
if(meaning != null) {
meaning = meaning.trim();
}
if(f_msg3.equalsIgnoreCase(meaning)) {
txtView.setText(f_msg3);
} else {
txtView.setText(f_msg);
}
...
A StringTokenizer takes care of numbers (the cause for your error) and other "tokens" - so might be considered to invoke too much complexity.
String[] pair = line.split("\\s*\\:\\s*", 2);
if (pair.length == 2) {
String word = pair[0];
String meaning = pair[1];
...
}
This splits the line into at most 2 parts (second optional parameter) using a regular expression. \s* stands for any whitespace: tabs and spaces.
You could also load all in a Properties. In a properties file the format key=value is convention, but also key:value is allowed. However then some escaping might be needed.
ArrayList vals = new ArrayList();
String jmeno = "Adam";
vals.add("Honza");
vals.add("Petr");
vals.add("Jan");
if(!(vals.contains(jmeno))){
vals.add(jmeno);
}else{
System.out.println("Adam je už v seznamu");
}
for (String jmena : vals){
System.out.println(jmena);
}
try (BufferedReader br = new BufferedReader(new FileReader("dokument.txt")))
{
String aktualni = br.readLine();
int pocetPruchodu = 0;
while (aktualni != null)
{
String[] znak = aktualni.split(";");
System.out.println(znak[pocetPruchodu] + " " +znak[pocetPruchodu + 1]);
aktualni = br.readLine();
}
br.close();
}
catch (IOException e)
{
System.out.println("Nezdařilo se");
}
try (BufferedWriter bw = new BufferedWriter(new FileWriter("dokument2.txt")))
{
int pocetpr = 0;
while (pocetpr < vals.size())
{
bw.write(vals.get(pocetpr));
bw.append(" ");
pocetpr++;
}
bw.close();
}
catch (IOException e)
{
System.out.println("Nezdařilo se");
}
There is a space between before and after = ...
( Backup = True )------ is a String to search(Even space is there between =)
File file = new File(
"D:\\Users\\kbaswa\\Desktop\\New folder\\MAINTENANCE-20150708.log.txt");
Scanner scanner = null;
try {
scanner = new Scanner(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// now read the file line by line...
int lineNum = 0;
while (scanner.hasNextLine()) {
String line = scanner.next();
lineNum++;
String name="Backup = True";
if (line.contains(name)) {
System.out.println("I found "+name+ " in file " +file.getName());
break;
}
else{
System.out.println("I didnt found it");
}
}
}
Scanner.next() returns the next complete token, so it will be returning something like Backup, then = next time round the loop, then true next time.
Use Scanner.nextLine() to get the entire line in one go.
scanner.nextLine() would solve your problem.
If you want to stick with scanner.next() you can define a delimiter: scanner.useDelimiter("\n") this reads the file until it hits the delimiter and starts the next loop from there.
You need to read the file line-by-line and search for your string in every line. The code should look something like:
final Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
final String lineFromFile = scanner.nextLine();
if(lineFromFile.contains(inputString)) {
// a match!
System.out.println("Found " +inputString+ " in file ");
break;
}
}
Now to decide between Scanner or a BufferedReader to read the file, check this link. Also check this link for fast way of searching a string in file. Also keep in mind to close scanner once you are done.
So, I'm trying to set up a simple config for a project. The goal here is to read certain values from a file and, if the file does not exist, to write said file. Currently, the creation of the file works fine, but my Scanner is acting a bit funny. When I reach the code
case "resolution": resolution = readConfig.next();
it makes the value of resolution "1024x768\nvsync" whereas it should only be "1024x768". If it were working as I planned, then the next value for
readingConfig = readConfig.next();
at the beginning of my while loop would be "vsync", which my switch statement would then catch and continue editing the values to those of the file.
Why is my Scanner picking up on the "\n" that is the 'enter' to the next line in the text document?
public static void main(String[] args) {
int musicVol = 0;
int soundVol = 0;
String resolution = null;
boolean vsync = false;
Scanner readConfig;
String readingConfig;
File configFile = new File(gameDir + "\\config.txt");
if (configFile.exists() != true) {
try {
configFile.createNewFile();
PrintWriter writer = new PrintWriter(gameDir + "\\config.txt");
writer.write("resolution = 1024x768 \n vsync = true \n music = 100 \n sound = 100");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
readConfig = new Scanner(configFile);
readConfig.useDelimiter(" = ");
while (readConfig.hasNext()) {
readingConfig = readConfig.next();
switch (readingConfig) {
case "resolution":
resolution = readConfig.next();
break;
case "vsync":
vsync = readConfig.nextBoolean();
break;
case "music":
musicVol = readConfig.nextInt();
break;
case "sound":
soundVol = readConfig.nextInt();
break;
}
}
readConfig.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Instead of using .hasNext and .next(), you will have to use .hasNextLine() and .nextLine(). I would write this as a comment, but do not have enought rep to comment yet.
You are using next() which will not delimit your lines, try using nextLine() instead:
String nextLine() Advances this scanner past the current line and
returns the input that was skipped.
I'd suggest not using the delimiter, and get the whole line instead as a string, and then split the string to the parts you want.
Something like
String nextLine = readConfig.nextLine();
String[] split = nextLine.split(" = ");
String resolution = split[1]; // just an example
...
Aha, solved!
What this does is pull the entire text file into a String (using Scanner.nextLine() removes the '\n') and then adds the " = " at the end of each line instead. Thus, when the Scanner runs back over the String for the switch, it will already be ignoring the " = " and pull the desired information from the String.
String config = "";
try {
readConfig = new Scanner(configFile);
while (readConfig.hasNext()) {
config += readConfig.nextLine() + " = ";
readConfig = new Scanner(config);
readConfig.useDelimiter(" = ");