I'm having a hard time terminating a java loop - java

I'm sure if you read the snippet you'll understand what I'm trying to do. However, I tried it first with null and "". I think .eoln() won't work because I'm asking for multiple lines of input, of which all have an end of line. I would preferably have the loop terminate when the user returns an empty line. For some more background, I've used the ==/!= and .equals() operators/method to experiment. I also just tried a do/while to no avail.
The asterisks were added to test if the empty string was an issue for the while statement.
Can anyone explain what I clearly don't understand about Java/TextIO yet?
EDIT - Revised Code Snippet:
while(write){
pl("Begin writing content to fill file.");
pl("");
pl("Return a line with a single SPACE or");
pl("\"\\n\" to represent line breaks in your");
pl("");
pl("Return two asterisks ** when done writing,");
pl("and you will be then prompted to select a file");
pl("to save your writing to.");
String input = TextIO.getln();;
String value = new String();
while(!(input.equals(""))) {
if (input == " " || input == "\\n") {
value += "\\n" + "\\n";
} else {
value += input + " ";
} // end if/else //
input = TextIO.getln();
} // end while(input) //
TextIO.writeUserSelectedFile();
p(value);
TextIO.writeStandardOutput();
pl("Would you like to write to another file?");
Boolean cont = TextIO.getBoolean();
write = cont;
}
}

Related

How to ask user for ONLY one word string input and produce error prompt in a try-catch block

EDIT: I figured it out! I got rid of the try-catch block because it just didn't work the way I wanted it to. The code below is my final one. Thank you to everyone who responded to this question.
I am trying to code a to-do list program. One function of this program is to search for the entries inside the string array. The user should only input a ONE WORD keyword so if the user inputs more than one word or none, a prompt should show telling the user to try again. The code I've written so far is inside a try-catch statement. Using next() scanner only takes the first word and disregards the rest when inputting a multiple-word keyword, instead of producing an Exception. Here is my code for it:
case 2:
String searchKeyword;
int success = 0;
while(success==0) {
System.out.print(">> Enter 1 keyword: ");
searchKeyword = sc.nextLine();
String splitSearchKeyword[] = searchKeyword.split(" ");
if (splitSearchKeyword.length == 1) {
if(Quinones_Exer2.searchToDoList(searchKeyword, todoList)==-1) {
System.out.println(">> No item found with that keyword!");
System.out.println();
}
else {
System.out.println(">> Found one item!");
System.out.println("("+(Quinones_Exer2.searchToDoList(searchKeyword, todoList)+1)+")"+" "+todoList[Quinones_Exer2.searchToDoList(searchKeyword, todoList)]);
System.out.println();
}
success++;
}
else {
System.out.println(">> Please input a single word keyword!");
System.out.println();
}
}
break;
}```
Use Scanner.nextLine() then split the supplied string. If the length of array is greater than 1 or the supplied string is empty then issue an invalid entry message and have the User enter the string over again:
while(tries2 == 0) {
searchKeyword = "";
while (searchKeyword.isEmpty()) {
System.out.println("Enter 1 keyword: ");
searchKeyword = sc.nextLine().trim();
if (searchKeyword.isEmpty() || searchKeyword.split("\\s+").length > 1) {
System.out.println("Invalid Entry! {" + searchKeyword
+ "You must supply a single Key Word!");
searchKeyword = "";
}
}
tries2++;
// ... The rest of your code ...
}
From the docs of Scanner.next():
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
You would need to call next() again to get the the rest of the input.
Much simpler would be to use Scanner.nextLine() to get entire line and then use String.split() with whatever delimiter you are using to get an array of all inputted keywords.
Edit: Scanner.next(pattern) may do what you are looking for. It throws InputMismatchException if the input does not match provided pattern(regex). Example:
scanner.next("^[a-zA-Z]+$")
This requires the entire line to consist of lower and/or upper case letters and nothing else.

RPN Calculator using Scanner, If/Else statement not reading

I am working on a very simple reverse polish notation calculator using stacks, and having trouble with an if/else statement inside a while loop. The rest of the code is working correctly, but I keep getting a NumberFormatException after the else line. I think this means it is not doing what it says to do in the if statement when the input is "*", but I am not sure how to fix this. Why would it go to else if the input is equal to one of the specified characters? I am not interested in making code more efficient, I would like to keep the format I have if possible, but I am very confused. Thank you so much for your help.
try {
Scanner stackScanner = new Scanner(stackFile);
while (stackScanner.hasNextLine()) {
String pls = "+";
String min = "-";
String mul = "*";
String div = "/";
String mod = "%";
String exp = "^";
//stackScanner.nextLine();
if(stackScanner.nextLine().equals(pls) ||
stackScanner.nextLine().equals(min) ||
stackScanner.nextLine().equals(mul) ||
stackScanner.nextLine().equals(div) ||
stackScanner.nextLine().equals(mod) ||
stackScanner.nextLine().equals(exp)) {
stack.push(new operationNode(stackScanner.nextLine()));
}
else {
stack.push(new
numberNode(Double.parseDouble(stackScanner.nextLine())));
}
}
stackScanner.close();
The nextLine() method of Scanner reads the next line. If you call it more than once, it will read more than one line. So this statement:
if(stackScanner.nextLine().equals(pls) ||
stackScanner.nextLine().equals(min) ||
stackScanner.nextLine().equals(mul) ||
stackScanner.nextLine().equals(div) ||
stackScanner.nextLine().equals(mod) ||
stackScanner.nextLine().equals(exp)) {
stack.push(new operationNode(stackScanner.nextLine()));
}
Here's what it does:
Reads a line, and tests if it's equal to "+". If it's not:
Reads another line, and tests if that second line is equal to "-". It doesn't test the same line that it tested against "+"--it tests the next line. If it's not "-":
Reads another line ... you get the picture.
Solution: Read the line once and save the result in a variable. (I don't know whether this will solve the entire problem. But you definitely need to fix this.)

Check for escape character in Java

I have a flat comma separated file that has "\N" for some rows. I need to load all rows and skip all those are not containing \N.
I am trying to do the following but it doesn't work.
if (!line.contains("\\N")) {
//do load here
}
Above code still passes the line from csv below:
1,text,abc,\N,23,56
and then we have NumberFormatException (it should be Int Value there).
Why is this happening?
If you want to only process file lines that contain a \N then omit the ! (exclamation) character from your if statement condition. This is the NOT flag.
What your condition is basically saying right now is:
If the current text file line contained within the string variable
line does NOT contain a \N then do execute the code within the if statement block.
IF statements are only executed if the supplied condition is boolean true. Applying the ! flag basically sets the condition to true if the supplied condition is NOT true. This may help you more.
If you want just those lines that DO contain a \N then your code should look like:
if (line.contains("\\N")) {
//process line here
}
If you DO NOT want to process those file lines that contain \N then what you are using right now should work just fine.
Regarding your question:
and then we have NumberFormatException (it should be Int Value there).
Why is this happening?
\n (lowercase n) is generally a tag which is applied within a string to force a New Line when processed, if a uppercase N is used it does not do this. In general, a lot of CSV files use the \N to mean NULL and others simply place nothing, just the delimiter. You will need to look into what is creating the CSV file to find the actual reason as to why since they may be using it for something else but for now you can consider it as NULL. Integer variables are never Null, they would be considered as containing 0 by default so you could change your code to:
if (line.contains("\\N") { line = line.replace("\\N", "0"); }
You could however also encounter \N where there should be a String so the above line will do you no good. One solution would be to handle \N within the contents of each array element (should it be there) after you have split the file line, for example:
String csvFilePath = "MyCSVfile.txt"; // assuming file is in classpath
try (BufferedReader br = new BufferedReader(new FileReader("MyCSVfile.txt"))) {
int j = 0; //used as a counter
String line = "";
while ((line = br.readLine()) != null) {
j++; //increment counter
String[] data = line.split(",");
//if the ID value contains null then apply the counter (j) value.
int id = Integer.parseInt(data[0].replace("\\N",String.valueOf(j)));
String type = data[1].replace("\\N","");
String text = data[2].replace("\\N","");
int value1 = Integer.parseInt(data[3].replace("\\N","0"));
int value2 = Integer.parseInt(data[4].replace("\\N","0"));
int value3 = Integer.parseInt(data[5].replace("\\N","0"));
System.out.println("ID is:\t\t" + id + "\nData Type is:\t" + type +
"\nText is:\t" + text + "\nValue 1 is:\t" + value1 +
"\nValue 2 is:\t" + value2 + "\nValue 3 is:\t" +
value3 + "\n");
}
br.close();
}
catch (IOException ex) {
//however you want to handle exception
}
This will handle the \N tag regardless of where it is encountered within any one of your CSV file lines.

Scanner return no new line in a while loop

Snippet of the code
while(!((input = sc.nextLine()) != null)) {
sc = new Scanner(input).useDelimiter(" ");
while (sc.hasNextLine()) {
in[index] = sc.next();
index++;
}
if (index < 3 || !in[0].equals("ping")) {
throw new IllegalArgumentException(
"Usage ping <destination> <port number missing> . . . ."
+ in[0] + " " + in[1] + " " + in[2]);
}
}
I want to keep reading user inputs but after the first iteration, i get no new line found. Scanner does not wait for the user input but rather advances on.
Thanks
Your top-level while loop is doing the opposite of what you want. First it sets input equal to sc.nextLine(), which is good. Then input is compared to null. If this comparison yields true, then you have input, which means that the loop should continue. However, you are then negating the result of that comparison, which makes the loop terminate when there is input.
Remove the exclamation point, and you should be good.
EDIT
On second thought, your inner while loop is exiting when sc.hasNextLine() returns false. After that, you will go through the conditional statement and return to the top. Since sc.hasNextLine() already returned false, of course sc.nextLine() will return null. The input has already ended in the inner loop, so the outer loop will exit as well.

do-while loop not working as it should

Ok so basically I am having trouble finding out why this is not working as I think it should, and need help getting to the right output. I have tried messing with this format a few ways, but nothing works, and I really don't understand why. Here are the instructions, followed by my source for it:
INSTRUCTIONS
Write a loop that reads strings from standard input where the string is either "land", "air", or "water". The loop terminates when "xxxxx" (five x characters) is read in. Other strings are ignored. After the loop, your code should print out 3 lines: the first consisting of the string "land:" followed by the number of "land" strings read in, the second consisting of the string "air:" followed by the number of "air" strings read in, and the third consisting of the string "water:" followed by the number of "water" strings read in. Each of these should be printed on a separate line.
ASSUME the availability of a variable, stdin , that references a Scanner object associated with standard input.
SOURCE:
int land = 0;
int air = 0;
int water = 0;
do
{
String stdInput = stdin.next();
if (stdInput.equalsIgnoreCase("land"))
{
land++;
}else if (stdInput.equalsIgnoreCase("air"))
{
air++;
}else if (stdInput.equalsIgnoreCase("water"))
{
water++;
}
}while (stdin.equalsIgnoreCase("xxxxx") == false); // I think the issue is here, I just dont't know why it doesn't work this way
System.out.println("land: " + land);
System.out.println("air: " + air);
System.out.println("water: " + water);
You are storing user info in stdInput but your while checks stdin. Try this way
String stdInput = null;
do {
stdInput = stdin.next();
//your ifs....
} while (!stdInput.equalsIgnoreCase("xxxxx"));
This Works:)
I just submitted this code to codelab and it works just fine.
Write a loop that reads strings from standard input where the string is either "land", "air", or "water". The loop terminates when "xxxxx" (five x characters ) is read in. Other strings are ignored. After the loop, your code should print out 3 lines: the first consisting of the string "land:" followed by the number of "land" strings read in, the second consisting of the string "air:" followed by the number of "air" strings read in, and the third consisting of the string "water:" followed by the number of "water" strings read in. Each of these should be printed on a separate line.
int land = 0;
int air = 0;
int water = 0;
String word = "";
while(!(word.equals("xxxxx"))) {
word = stdin.next();
if(word.equals("land")) {
land++;
}else if(word.equals("air")) {
air++;
}else if(word.equals("water")) {
water++;
}
}
System.out.println("land:" + land);
System.out.println("air:" + air);
System.out.println("water:" + water);
I think you want stdInput.equalsIgnoreCase("xxxxx") == false instead of stdin.equalsIgnoreCase("xxxxx") == false.
You are right - the problem is where you indicated. The solution is to not read again from stdin:
Also, you must declare the stdInput before the loop so its scope reaches the while condition:
String stdInput = null;
do {
stdInput = stdin.next();
// rest of code the same
} while (!stdInput.equalsIgnoreCase("xxxxx"));
An alternate way would be a for loop:
for (String stdInput = stdin.next(); !stdInput.equalsIgnoreCase("xxxxx"); stdInput = stdin.next()) {
// rest of code the same
}

Categories

Resources