line.startsWith does not interprete the string - java

I am trying to not print lines start with string like 2 2 but with the current state just line starts with notice are being delteted. I debugged it and wrote the Output in the code lines. How can I fix it?
I appreciate any help.
Code:
int number = Character.getNumericValue(newName.charAt(2));
//here start_zero is `2 2`
String start_zero = new StringBuilder().append(number)
.append(" ").append(number).toString();
try (PrintWriter writer = new PrintWriter(path + File.separator
+ newName);
Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
//here is the first line `2 2`
String line = scanner.nextLine();
//here is start_zero `2 2` too.
if (!line.startsWith("notice") || !line.startsWith(start_zero) ) {
writer.println(line);
writer.flush();
}
}
} catch (Exception e) {
e.printStackTrace();
}

if (!line.startsWith("notice") || !line.startsWith(start_zero) ) {
writer.println(line);
writer.flush();
}
your problem is in your if statement. You used OR, but you should have used AND
if (!line.startsWith("notice") && !line.startsWith(start_zero) ) {
writer.println(line);
writer.flush();
}
if the first returns true ... which is your case, the second doesn't matter anymore in your code.

Just change your if statement operator from OR to AND like this
if (!line.startsWith("notice") && !line.startsWith(start_zero) )
{rest of code here}

This condition:
if (!line.startsWith("notice") || !line.startsWith(start_zero) )
Means: "Do the following if the line doesn't start with "notice" or if the line doesn't start with "2 2".
It means that if the line doesn't start with "notice", the whole condition becomes true. Because it's correct to say that the first or the second conditions were met when just one of them is met.
If you want to print the line only if it neither starts with "notice" nor with "2 2", you have to use one of these conditions:
! ( line.startsWith("notice") || line.startsWith(start_zero) )
(Note: the parentheses are important.) Or the equivalent (by DeMorgan's law):
! line.startsWith("notice") && ! line.startsWith(start_zero)
The first can be interpreted as 'Do the following if it's not true that the line starts with either "notice" or "2 2"', and the second as 'Do the following if the line both doesn't start with "notice" and doesn't start with "2 2"'.

Related

How to implement an input in a loop

I wanted to create a loop where I can input my name using a Scanner, but the system keeps spamming "Gimme your name" and doesn't leave me the chance to input my name. I want the system to output "Gimme your name" and wait for my input.
Scanner sc = new Scanner(System.in);
char reponse = 'O';
name = sc.nextLine();
while (reponse=='O')
System.out.println("Gimme your name! ");
name = sc.nextLine();
System.out.println("Hello "+name+"How are you doing ? \n Wanna retry ? (O/N)" );
reponse = sc.nextLine().charAt(0);
Try putting open close brackets around the while statement:
char reponse = 'O';
name = sc.nextLine();
while (reponse=='O') {
System.out.println("Gimme your name! ");
name = sc.nextLine();
System.out.println("Hello "+name+"How are you doing ? \n Wanna retry ? (O/N)" );
reponse = sc.nextLine().charAt(0); ```
}
Because there is not a open and close bracket, the way the code was written may be read from the compiler like:
while (respose == 'O') System.out.println("Gimme your name! ");
The ending semicolon would "combine" the two lines into one, per se.
Include the open and closed bracket after the while loop and at the end of the looping statements to fix.

Buffered Reader: Reset won't reset

I'm currently learing about the mark() and reset() methods of the BufferedReader and want to do the following:
I parse a CSV, set up like this (spaces as delimiter):
555 value1
555 value2
600 foobar
700 whatever
Each line, one object (adress) is created with the first number as its ID. When the ID is used multiple times, I want to compare the values in the second column and proceed afterwards.
With the data above, my code does compare the two values with ID 555, but fails to create an object with the third line (ID 600).
Mistake found: splitted the first line after parsing the new one. Simple mix up of variables.
My setup is similar to this:
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
br.mark(1000); //save current line
List<String> list = new ArrayList<String>(Arrays.asList(line.split(delimiter)));
Adress a = new Adress(Long.parseLong(list.get(0)); //create object
while (((checkLine = br.readLine()) != null) && exit == false){
List<String> nextLine = new ArrayList<String>(Arrays.asList(line.split(delimiter)));
long nextId = Long.parseLong(nextLine.get(0));
if( nextId == a.getId() ){
System.out.println(nextId + " vs. " + a.getId());
br.mark(1000); //mark the next line if it has the same ID
//[...] do more stuff
} else{
exit = true;
}
}
br.reset(); //reset to the last line with the ID
}
Sysout:
555 vs. 555
555 vs. 555
555 vs. 555
I see a couple of issues in the code:
Inside the second while() loop you are still splitting the string "line", but the while loop assigns the input to "checkLine".
You don't reset "exit" to false - this should probably happen after the br.reset().
if your addresses are separated by spaces , and the different elements of your address are also separated by spaces , then this line does not give you addresses , it gives you elements .
List < String > list = new ArrayList < String > ( Arrays . asList ( line . split ( delimiter ) ) ) ;
The mistake was the following variable-mixup (solely my stupidity was the mistake!):
while (((checkLine = br.readLine()) != null) && exit == false){
List<String> nextLine = new ArrayList<String>(Arrays.asList(line.split(delimiter)));
[...]
The List nextLine has to be changed from line.split to checkline.split:
List<String> nextLine = new ArrayList<String>(Arrays.asList(checkLine.split(delimiter)));
Thanks to everybody helping!

Why does the compiler complain "while expected" when I try to add more code?

Write a program with a word containing # character as an input. If the word doesn't contain #, it should prompt the user for a word with #. Once a word with # is read, it should output the word then terminate.
This is what I have done so far:
public class find {
public static void main(String[] args) {
System.out.println(" Please enter a word with # ");
Scanner scan = new Scanner(System.in);
String bad = "#";
String word = scan.next();
do
if (!word.contains(bad))
System.out.println(" Please try again ");
else
System.out.println(" " + word);
while (!word.contains(bad));
}
}
I can get it to terminate after a word containing "#" is given as input, but if I try to add a Scanner to the line after "please try again", it says while expected.
I think issue is you are missing surrounding braces for do/while:
do
if (!word.contains( bad ))
System.out.println( " Please try again " );
else
System.out.println( " " + word);
while ( !word.contains( bad ));
should be:
do
{
if (!word.contains( bad ))
System.out.println( " Please try again " );
else
System.out.println( " " + word);
}while ( !word.contains( bad ));
Some people may not like this, but my suggestion is always use open/close braces. In this case, for the code if/else also. It avoids lot of confusion.
This is where your problem lies:
do
if (!word.contains(bad))
System.out.println(" Please try again ");
else
System.out.println(" " + word);
while (!word.contains(bad));
You need to put braces from where the loop starts until it ends. |So this thing should like:
do {
if (!word.contains(bad))
System.out.println(" Please try again ");
else
System.out.println(" " + word);
} while(!word.contains(bad));
For Better Practice You should Check do...while loops here.
The problem with your code is it is not re-reading the word in your loop.
Modify your loop like this (minimum change to your code).
do {
word = scan.next();
if (!word.contains(bad))
System.out.println(" Please try again ");
else
System.out.println(" " + word);
}
while (!word.contains(bad));
And yes as others have pointed out try to use braces especially with nested constructs.
There are two issues.
Your code is not using the braces properly
you are not attempting to read the new word if right word is not entered.
Also I prefer while loop better in the case as opposed to do-while loop as below.
Scanner scan = new Scanner ( System.in );
String required= "#";
System.out.println( " Please enter a word with # " );
String word = scan.next() ;
//check if the right word(containing #) is entered,
//if not then loop until it is enteres
while((!word.contains(required)){
System.out.println( " Please try again " );
//read the new word as input from the user
word = scan.next() ;
}
//right word is entered, display it
System.out.println(word);
Also please note that when you use scan.next(), it reads each word separately if entered in the same line.

Error Separating Multiple Rules in ANTLR

I've almost finished my first adventure with ANTLR, and it's been quite a trip. Unfortunately, always only counts in horseshoes, hand grenades, and nuclear weapons, right?
Anyways, I'm trying to parse an input that looks like this:
; IF AGE IS LESS THAN 21, STILL RETURN TRUE FOR OVERSEAS LOCATION \r\n
SHOW "AGE REQUIREMENTS FAILED" FOR \r\n
IF AGE < 21 THEN \r\n
LOCATION = "OVERSEAS" \r\n
ENDIF \r\n
\r\n
; NEED SOMEONE WHO HAS WORKED FOR US FOR > 1 YEAR EXCEPT FOR CEO \r\n
SHOW "MINIMUM TIME REQUIREMENT NOT MET" FOR \r\n
IF STARTDATE > TODAY - 1 YEAR THEN \r\n
EMPLID=001 \r\n
ENDIF \r\n
Generally, if the test fails, the message is shown.
Anyways, a set can contain 1 or more SHOW rules. Processing of a single SHOW rule works, but it won't "split" when an inputstream contains > 1 SHOW rules.
Here are the relevant rules from the grammar:
showGroup returns [List<PolicyEvaluation> value]
#init {List<PolicyEvaluation> peList = new ArrayList<PolicyEvaluation>();}
: (expr1=show)* {peList.add($expr1.value);}
{
System.out.println("Entered policyGroup rule");
$value = peList;
}
;
// evaluate a single SHOW statement
show returns [PolicyEvaluation value]
: ('SHOW' expr1=STRING 'FOR')? expr2=ifStatement EOL*
{
System.out.println("Entered show rule");
Boolean expr2Value = (Boolean) $expr2.value;
PolicyEvaluation pe = new PolicyEvaluation();
if (expr1 == null) {
pe.setValue(expr2Value);
pe.setMessage(null);
} else {
if (expr2Value == false) {
pe.setValue(false);
pe.setMessage(expr1.getText());
} else {
pe.setValue(true);
pe.setMessage(null);
}
}
$value = pe;
}
;
// rules leading up to the show rule
// domain-specific grammar rules
STRING: '"' ID (' ' ID)* '"'
{
System.out.println("Entered STRING lexer rule");
// strip the quotes once we match this token
setText(getText().substring(1, getText().length()-1));
}
;
COMMENT: ';' (ID|' ')* EOL {$channel = HIDDEN;};
EOL: ('\r'|'\n'|'\r\n') {$channel = HIDDEN;};
SPACE: ' ' {$channel = HIDDEN;};
Maybe this is something simple. Any help is appreciated.
Jason
Try changing this: (expr1=show)* {peList.add($expr1.value);}
to this: (expr1=show {peList.add($expr1.value);})*
The action as it is will only fire after all show matches have completed, leaving you to operate on the last expr1.

using tokenizer to read a line

public void GrabData() throws IOException
{
try {
BufferedReader br = new BufferedReader(new FileReader("data/500.txt"));
String line = "";
int lineCounter = 0;
int TokenCounter = 1;
arrayList = new ArrayList < String > ();
while ((line = br.readLine()) != null) {
//lineCounter++;
StringTokenizer tk = new StringTokenizer(line, ",");
System.out.println(line);
while (tk.hasMoreTokens()) {
arrayList.add(tk.nextToken());
System.out.println("check");
TokenCounter++;
if (TokenCounter > 12) {
er = new DataRecord(arrayList);
DR.add(er);
arrayList.clear();
System.out.println("check2");
TokenCounter = 1;
}
}
}
} catch (FileNotFoundException ex) {
Logger.getLogger(Driver.class.getName()).log(Level.SEVERE, null, ex);
}
}
Hello , I am using a tokenizer to read the contents of a line and store it into an araylist. Here the GrabData class does that job.
The only problem is that the company name ( which is the third column in every line ) is in quotes and has a comma in it. I have included one line for your example. The tokenizer depends on the comma to separate the line into different tokens. But the company name throws it off i guess. If it weren't for the comma in the company column , everything goes as normal.
Example:-
Essie,Vaill,"Litronic , Industries",14225 Hancock Dr,Anchorage,Anchorage,AK,99515,907-345-0962,907-345-1215,essie#vaill.com,http://www.essievaill.com
Any ideas?
First of all StringTokenizer is considered to be legacy code. From Java doc:
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
Using the split() method you get an array of strings. While iterating through the array you can check if the current string starts with a quote and if that's the case check if the next one ends with a quote. If you meet these 2 conditions then you know you didn't split where you wanted and you can merge these 2 together, process it like you want and continue iterating through the array normally after that. In that pass you will probably do i+=2 instead of your regular i++ and it should go unnoticed.
You can accomplish this using Regular Expressions. The following code:
String s = "asd,asdasd,asd\"asdasdasd,asdasdasd\", asdasd, asd";
System.out.println(s);
s = s.replaceAll("(?<=\")([^\"]+?),([^\"]+?)(?=\")", "$1 $2");
s = s.replaceAll("\"", "");
System.out.println(s);
yields
asd,asdasd,asd, "asdasdasd,asdasdasd", asdasd, asd
asd,asdasd,asd, asdasdasd asdasdasd, asdasd, asd
which, from my understanding, is the preprocessing you require for your tokenizer-code to work. Hope this helps.
While StringTokenizer might not natively handle this for you, a couple lines of code will do it... probably not the most efficient, but should get the idea across...
while(tk.hasMoreTokens()) {
String token = tk.nextToken();
/* If the item is encapsulated in quotes, loop through all tokens to
* find closing quote
*/
if( token.startsWIth("\"") ){
while( tk.hasMoreTokens() && ! tk.endsWith("\"") ) {
// append our token with the next one. Don't forget to retain commas!
token += "," + tk.nextToken();
}
if( !token.endsWith("\"") ) {
// open quote found but no close quote. Error out.
throw new BadFormatException("Incomplete string:" + token);
}
// remove leading and trailing quotes
token = token.subString(1, token.length()-1);
}
}
As you can see, in the class description, the use of StringTokenizer is discouraged by Oracle.
Instead of using tokenizer I would use the String split() method
which you can use a regular expression as argument and significantly reduce your code.
String str = "Essie,Vaill,\"Litronic , Industries\",14225 Hancock Dr,Anchorage,Anchorage,AK,99515,907-345-0962,907-345-1215,essie#vaill.com,http://www.essievaill.com";
String[] strs = str.split("(?<! ),(?! )");
List<String> list = new ArrayList<String>(strs.length);
for(int i = 0; i < strs.length; i++) list.add(strs[i]);
Just pay attention to your regex, using this one you're assuming that the comma will be always between spaces.

Categories