Counting number of times a character is inputted--Do-While Loops Java - java

I'm a bit confused as to why I need the do-while loop in this piece. What I am trying to do is count the number of times a user inputs a character. The count should stop when the user types a ".". When I try to run the program without the do-while, the count of x is multiplied by 3. I've read online that the console input is line buffered. The way I understand it, is a an entire line is created by one character and as such there are actually more characters? Is my understanding correct? And if possible, could I have an explanation of the do-while loop?
public class readCharLengths {
public static void main(String args[])
throws java.io.IOException {
char typed, ignore;
int x=0;
for ( ; ; ) { //infinite loop to keep reading in values
typed = (char) System.in.read(); //get typed character
do { //confused here
ignore = (char) System.in.read(); //confused here
} while (ignore != '\n'); //confused here
if (typed =='.') break; //break loop when . is typed
x++; //increment x
}
System.out.println("The number of characters is: " + x); //print x
}
}

It depends on the circumstances around how a user is giving input into the console. If they insert one character at a time, each on a separate line. Or if they input a string of characters, basically like a sentence, and then you count the number of characters until a period is reached.
If it is one character per line, I would suggest:
int x = 0;
Scanner in = new Scanner(System.in);
while (true) {
String input = in.nextChar();
if (input.equals('.') {
break;
} else {
x++;
}
}
If it is a string of characters, I would suggest:
int x = 0;
Scanner in = new Scanner(System.in);
String input = in.nextLine();
for (int i=0; i<input.length(); i++) {
if (input.charAt(i).equals('.') {
break;
} else {
x++;
}
}

To answer what a do...while loop is, I'm going to go into some very basic programming concepts. I don't mean to be condescending if I come across that way: I just don't know your skill level with programming, so I'm assuming you are very new to it.
First, let me explain the concept of a loop condition. A loop condition is code that, when it is evaluated while your program runs, will either come out to true or false. So, in the case of a regular while loop, the format is:
while (loop condition) {
run some code, maybe multiple times
}
When your code reaches the while line of code it evaluates the condition and decides whether to run the code inside the loop's braces.
Let's say your condition is "x must be less than 5". You might have a while loop like this:
int x = 0;
while(x < 5) {
System.out.println("A");
x++;
}
This code will print A on 5 lines because x = 0 when it reaches the while statement the first time, and since 0 < 5 evaluates to true, the loop's code is going to execute. When the end of the loop is reached, it jumps up to the loop condition and evaluates it again. This time, x = 1 because we added 1 to x. Since 1 < 5, the loop happens again. This happens a total of 5 times and then when it evaluates the loop condition, you have it try 5 < 5, which is false. It skips the loop code and continues the program at this point.
A do...while loop is based on the same idea. Instead of checking the loop condition at the start of the loop, it is checked at the end. So...
int x = 0;
do {
System.out.println("A");
} while(x < 0);
This code will output A once. Even though the loop condition is not met (since x starts at 0), when you use a do...while, the loop code is always executed at least once. At the end of the loop, the condition is checked and since 0 < 0 is false, the loop does not repeat.
So, on to how System.in.read() works. You have it right that it buffers the input until a linebreak is reached. But do you actually know what that means?
Here's how it works. You start typing stuff into the console. Say you type aabbcc and then press enter. Your program waits when it calls System.in.read() until user input is sent back to the program. It does not continue running when the first a is typed though! Your program only gets to continue running once you press enter (that is, a linebreak is sent).
The idea of buffering input is that all the letters you typed are stored and available once your program starts running again. So when your program runs after you have entered aabbcc, all of those letters are available (and also the linebreak for the enter key you pressed).
With your code, that means that the first time you call System.in.read(), you get back the character a, but there is still abbcc and newline waiting. It enters the loop and reads each character. So it reads a, then b, then b, then c, then c, then newline. At this point the loop condition is false and the loop ends.

Well, there are a couple of things about this.
First, this might not do what you want because the do/while loop will consume every character after the first one without incrementing the counter until it hits the LF. So, your count will always be 1 with the do/while loop in place assuming you type at least one character and then hit Enter. However, if your intention is that the user is allowed to enter only one character at a time (followed by Enter), then see the second item.
Second, console input defaults to buffered until you press Enter. So, if you take the do/while loop out, enter a single character and press Enter, you'll actually get three characters on Windows--the character you typed, CR and LF. Assuming you're testing with single characters, that would explain the multiplication by 3.

Related

Debugging do-while loop appear more than one statements

I write a code for o-while loop where I take an input from user and check if it is equal to 'c' or 'C' the exit from the loop. If input other than c or C entered the internal statement of do block is appearing 3 times and if i just enter press without pressing any character then do block's inner statement appears 2 times why?? Can anyone explain
int ch = 0;
do {
System.out.println("Press C or c to continue.");
ch = System.in.read();
}
while(ch !='C' && ch !='c');
(Judging from the output you described, you are probably on a Windows machine, right?)
read returns the next character in the input stream. When you enter C or c, and then press enter, you have actually entered three characters:
c
\r
\n
The last two characters together is the Windows way of representing a new line. Since there are three characters to read, read gets called three times before you are prompted to enter anything again, so println gets called three times as well.
If you just press enter, then you have only entered two characters:
\r
\n
so two lines are printed.
To fix this, you can use a java.util.Scanner. Scanner has a nice method called nextLine, which returns everything the user enters until it reaches a new line character.
Scanner sc = new Scanner(System.in);
String line = "";
do {
System.out.println("Press C or c to continue.");
line = sc.nextLine();
}
while(!ch.equals("C") && !ch.equals("c"));

How to return last letter in ArrayList and return total number of letters entered?

I have been trying to do a question as follows:
The program should keep prompting the user to enter a letter until the user types ‘!’, which ends the program. Each time the use enters a letter, the program should add the letter to the previous letters entered and print the result. The program should also return:
the last entered letter when ‘#’ is entered.
the total number of letters entered when ‘#’ is entered.
I am stuck on how to return the last entered letter and returning number of letters entered. I thought about if statements but they don't seem to be working. Here is my code so far:
import java.util.Scanner;
import java.util.ArrayList;
public class check {
static Scanner input = new Scanner (System.in);
static ArrayList<String> array= new ArrayList<>();
public static void main(String[] args) {
System.out.print("Please enter a letter: ");
String a=input.nextLine();
while ( !a.equals("!")) {
array.add(a);
for(String b : array) {
System.out.print(b);
}
System.out.print("\n"+"Please enter a letter: ");
a=input.nextLine();
}
// array.add(a);
if((a.equals("#"))) {
ArrayList.get(ArrayList.size()-1);
for(String b : array) {
System.out.print(b);
}
}
I know the if statement I have done is incorrect because it's giving red line under. But don't know how and what to do next.
Here's what your code does line by line:
while ! is not the key that is pressed, add the key that was pressed to an ArrayList of Strings called "array." After that, print out every string in "array," and then wait for the next keypress.
If ! is pressed, the while loop doesn't occur (nothing is added to the array, nothing is printed out, there is no .nextLine()).
At this point, if that last key wasn't "#," do nothing and the program terminates. If it was, make a static call to
ArrayList.get() //(this is a compilation error)
then make a static call to
ArrayList.size() - 1 //(another compilation error).
To fix these errors and clean the code up to make it readable, it should be written as:
if(a.equals("#")){ //Remove the superfluous parentheses
array.get(array.size() - 1);
When you change that line, you will now be doing this: if that last key was "#," get the last string in the array and do nothing with it (I assume you want a System.out.println() here, as doing a array.get(array.size() - 1) but not assigning it to a variable does nothing). After doing essentially nothing, take every string in array and print it out.
The problems should be apparent if you talk out what you're code is doing like this; it can really help! You will have to change the program a bit to accomplish what you want as well.
In my opinion what you want to do is a while loop that checks !a.equals("!") because we still want ! to end the program. However, in the while loop you need add an if and an else if after you print out the values in the array: the if checks to see if the key entered was a "#" and if it is, print a... the else if checks to see if the key was "#" and if it is print array.size().
That's IF you're reading the requirements for the assignment right too; it could be that you're supposed to be doing string concatenation instead of populating an ArrayList, i.e., declare stringBuilder outside while block, and inside while block:
if (stringBuilder == null){
stringBuilder = new StringBuilder(a);
}
stringBuilder.append(a);
//print stringBuilder and then print a or stringBuilder.length()

findWithinHorizon(".",0).charAt(0) Clarification

I'm having trouble understanding the source below:
myChar1 = myScanner.findWithinHorizon(".",0).charAt(0);
System.out.println(myChar1);
myChar2 = myScanner.findWithinHorizon(".",0).charAt(0);
System.out.print(myChar2);
I understand what it does, but I'm just having a bit of a trouble understanding how it works.
The actual prompting of the user for input is done at the first line right? but the real meaning of the first line is: "put the first char of input in myChar1". Then what happens? It seems the input still stays inside myScanner because when I use it in myChar2 I get the second char, but why? why not the first char? Does findWithinHorizon(".",0).charAt(0) deletes the char that is assigned to the variable?
And last question: if in the first line the program prompts the user for input why doesn't it do it again in the second line?
Also, a quick recap of the (".",0) would be helpful as well.
Perhaps the piece you are missing is that findWithinHorizon actually takes a regular expression as the String argument. In a regular expression, . matches any character (except a new line).
A call to findWithinHorizon(".", 0) simply finds the next character in the input and advances the Scanner past whatever was found.
So for example,
Scanner in = new Scanner("abc123");
for(;;) {
String found = in.findWithinHorizon(".", 0);
if(found == null) break;
System.out.println(found);
}
the output is:
a
b
c
1
2
3
The reason it does not prompt for input at the second line is that is the way Scanner and System.in work together. They will only block and prompt for input if there is no more existing input to consume. As a short example, try this out:
Scanner in = new Scanner(System.in);
while(true) {
System.out.println(in.findWithinHorizon(".", 0));
}
That will loop infinitely, repeating back whatever you input, character by character. It will only prompt for more when it's done with the prior input. On the first iteration, Scanner will call read on System.in which will block and wait for input. When the input runs out, read will block again.

While Loop executing one last time when condition is set to false

Task: To check that if a user input string has the same first and last character. If yes or no, output to the screen, if the user enters "done", the loop is exited.
Issue: While loop executes when condition is false
What I've tried: Using different types of loops, doing a loop within the loop to revalidate the code and all together giving up!
import java.util.*;
public class lab_15 {
public static void main(String args[]) {
String userInput = "";
String done = "done";
while (!userInput.equalsIgnoreCase(done))
{
int length;
Scanner sc = new Scanner(System.in);
userInput = sc.next();
length = (int)userInput.length();
if (userInput.charAt(0) == userInput.charAt(userInput.length()-1)) {
System.out.println("The first character equals the second character.");
}
else {
System.out.println("The first and second characters are different.");
}
}
// EXIT LOOP
System.out.println("Thank you for using this software!");
}
}
Inputs
+ bradley
+ hannah
+ done
I am still new to the site and have referred to the t's & c's regarding posts. Please do not negative if you find the question to not be challenging. I am new to programming and hope to progress.
Thank you!!!
This is because you change your userInput immediately once entering the loop. The condition is only checked when you reach the top of the loop, so if you invalidate the condition halfway through, it will continue executing until you reach the top.
The solution is to refactor so that the very last thing that happens is changing your userInput so that the condition is check immediately after the value is changed. (I would also pull the scanner instantiation out of the loop.)
Alternatively you could check your condition inside of the while loop and call break if the userInput has changed to match the terminating condition. The break keyword will force the logic to exit the loop immediately, without evaluating the condition again.

Scanner asking more strings that expected

I'm trying to take string in input using Scanner.
But it asks me more strings that expected: shouldn't with this code ask 5 strings?
public void go()
{
Scanner sc=new Scanner(System.in);
ArrayList<String> list=new ArrayList<String>();
String temp=new String();
Integer i=new Integer(0);
while(sc.hasNextLine() && i<5)
{
temp=sc.nextLine();
list.add(list.size(),temp);
i++;
}
}
If I try to run it it asks me 6 strings before the console stops to take input.
But i at the beginning is zero, it gets incremented 5 times before becoming 5.
So why it also remain in while when i is 5?
Solved: Both methods solved the problem.
You have a misunderstanding on your code's execution.
It asks you 6 strings but adds 5 of them to the list.
The reason it asks you one more string is that, sc.hasNextLine() is executed, it's evaluated to true, so you see the console is expecting you to enter something, but then 2nd part of the loop condition comes: i<5, this is evaluated to false so the loop body is skipped and you have 5 strings in your list. You can see these in action by debugging your code in Eclipse or Netbeans or another Java IDE.
Just for convenience simplify your loop. Remove sc.hasNextLine() from loop condition.
while( i < 5 )
{
temp=sc.nextLine();
list.add(list.size(),temp);
i++;
}
If i == 5 still a sc.HasNextLine() is called. Repair:
while (i < 5 && sc.hasNextLine())
P.S. do int i = 0;

Categories