Input function get wrong value after recall in Java? - java

I have a problem is when i input value for array 2d with value valid, everything done but when i input wrong value for totalRow or totalColumn variable then my Input function forced me to input double and get value in 2nd.
It is my code:
public static void input() {
Scanner sc = new Scanner(System.in);
try {
System.out.println("Input total totalRow: ");
totalRow = sc.nextInt();
// verify value input must be a positive integer and greater than zero
if (totalRow <= 0) {
System.out.println("Input value must be a positive integer and greater than zero!");
input();
}
System.out.println("Input total totalColumn: ");
totalColumn = sc.nextInt();
// verify value input must be a positive integer and greater than zero
if (totalRow <= 0) {
System.out.println("Input value must be a positive integer and greater than zero!");
input();
}
// check case array must be square array
if (totalRow != totalColumn) {
System.out.println("Array must be square!");
input();
}
} catch (InputMismatchException e) {
// print message when user input other than integer
System.out.println("Please input an integer!");
input();
}
// initialize array with totalRow and totalColumn
array = new char[totalRow][totalColumn];
// input value for array
for (int i = 0; i < totalRow; i++) {
for (int j = 0; j < totalColumn; j++) {
array[i][j] = sc.next().charAt(0);
}
}
}
Example: I enter 2 and a for totalRow and totalColumn: message appear and i re-enter is 2 and 2, but i have entered 1 2 3 4 5 6 7 8 for array and value get from 5.

You have a couple of things here that are making your code to fail:
Typo: you are checking totalRow <= 0 twice (copy paste error for sure)
If condition not met, then you call input again:
doing this will make a recursive implementation of the method, that can lead to a not desired repetition of the sequence, driving crazy the user and the developer
you are forgetting that scanner.nextInt does not consume the last newline character of your input
I would suggest to modify the Code by doing something like:
if (totalRow <= 0) {
System.out.println("Input value must be a positive integer and greater than zero!");
//input();
}
System.out.println("Input total totalColumn: ");
totalColumn = sc.nextInt();
sc.nextLine();
// verify value input must be a positive integer and greater than
// zero
if (totalColumn <= 0) {
System.out.println("......

There is a problem with Recursion algorithm. Even it works for a correct input, foe a wrong input it will repeatedly ask for values. Since when you make any mistake Input() function will start again from the beginning. So if you want to use recursion better to use separate functions for input_Total_Column() and input_Total_Row() .
And there is also a copy paste error. You are checking totalColumn<=0 twice in your code.
//Your code//
`for (int i = 0; i < totalRow; i++) {
for (int j = 0; j < totalColumn; j++) {
array[i][j] = sc.next().charAt(0);
}
}
}`
if you enter the values in a raw this seems to be a incorrect logic. charAt(0) will return a charactor at the inedex 0(Only . So always it wold be returning the charactor at begining. Try it like this.
string array_input= sc.nextLine();
split the string using .split() function.
then you can easily convert the values to integer using Integer.parseInt() at corresponding string value.

Related

JAVA Method returns unexpected value

I am a very new java programmer, the below code is my first attempt at my own project. I'm certain the code is a mess, please forgive me.
In the below code the user is prompted to enter 5 values between 1 and 50.
I am placing the input values into an int[].
I want to verify that the numbers are in range so I pass the value to a method.
MY ISSUE:
If the value is in range it gets returned then the for loop increments to repeat - Good Behavior
If an invalid value is entered the check is done, error message is displayed and the user is prompted to reenter a proper value.
If one invalid entry is made and a proper value is entered on the second attempt, a correct value is returned - Good Behavior
If two invalid entries are made the second invalid entry somehow gets passed back to the for loop and gets added to array - BAD Behavior
I am certain there is something simple I am missing.
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("you get 5 elements between 01 & 50:");
int a[] = new int[5];
System.out.println("\nEnter all the elements:");
for(int i = 0; i < 5;)
{
int b = in.nextInt();
a[i] = checkNum(b);
i++;
}
System.out.println("Numbers:" + Arrays.toString(a));
in.close();
}
static int checkNum(int z) {
Scanner s = new Scanner(System.in);
if (z>0 && z<51) {
return z;
} else {
System.out.println("Invalid Entry!! Enter a valid number between 01 & 50");
int qz = s.nextInt();
z = qz;
checkNum(qz);
}
return z;
}
The problem resides in your checkNum(), you are using recursion here, I don't think you know this (if you do that's great).
You need to return the checkNum(qz) value, I have simplified your logic a bit.
static int checkNum(int z) {
if (z<1 || z>50) // check for false value
{
System.out.println("Invalid Entry!! Enter a valid number between 01 & 50");
Scanner s = new Scanner(System.in);
return checkNum(s.nextInt());
}
return z;
}
You could follow a simpler approach assuming the user will input numbers and not other characters (that would throw an exception),
public static void main(String[] args) {
System.out.print("you get 5 elements between 01 & 50:");
Scanner in = new Scanner(System.in);
int a[] = new int[5];
int i = 0;
do{
System.out.println("Enter an element:");
int b = in.nextInt();
if (b > 0 && b < 51){
a[i] = b;
i++;
}else{
System.out.println("Invalid Entry!! Enter a valid number between 01 & 50");
}
}while(i < 5);
in.close();
System.out.println("Numbers:" + Arrays.toString(a));
}
Here you're asking for valid input until the threshold of 5 is reached. Because you don't know beforehand how many times the user will provide input, until the criteria are met, a do-while loop is used.

Checking whether a number is an Unique number or not

I have written a program to check if a number is an Unique number.
[A Unique number is a number with no repeating digits and no leading zeros.]
I have written the following code:
Scanner sc=new Scanner(System.in)
System.out.println("Enter the number to be checked: ");
String num=sc.nextLine();
if(num.charAt(0)!='0')
{
Outer:
for(int i=0;i<num.length();i++)
{
for(int j=0;j<num.length();j++)
{
if(num.charAt(i)==num.charAt(j))
{
System.out.println("No, "+num+" is not a Unique number.");
break Outer;
}
}
if(i==num.length()-1)
{
System.out.println("Yes, "+num+" is a Unique number.");
}
}
}
else
System.out.println("No, "+num+" is not a Unique number as it has leading zeros.");
The problem is that is shows any number as NOT Unique, even 12345.
I would like to know where I have gone wrong.
Your code will always find "duplicate" characters when i == j.
You should change the indices of the loop in order not to compare a character to itself:
for(int i=0;i<num.length();i++) {
for(int j=i+1;j<num.length();j++) {
if(num.charAt(i)==num.charAt(j))
...
Besides, you should only output the "...is a Unique number." message after you are done with the outer loop.
Lets assume , length of input number to be 10 and "i" has reached the value of 5 in the for loop.
Now "j" will have the values 0 to 9.
So when "j" is equal to 5 , the if condition becomes true as you are comparing the digit at 5th position with itself (which is always true).
If you add i != j condition , it will fix the issue :-
if(num.charAt(i)==num.charAt(j) and i != j)
Alternatively, you can modify the loop for j to start from i + 1 so
that there are no overlaps.
for(int j=i+1;j<num.length();j++)
The second option is much better as it will reduce the number of comparisons from (n*n)
to (n * (n - 1))/2) , where n is the number of digits in the input number.
A possible solution is to use Stream to convert your String in a Set of char, then if the size of the set is the same as the length of your string, it is unique:
Scanner sc = new Scanner(System.in);
System.out.println("Enter the number to be checked: ");
String num = sc.nextLine();
boolean unique = Stream.of(num.split(""))
.map(s -> new String(s))
.collect(Collectors.toSet()).size() == num.length();
// With "1234" -> print true
// With "12342" -> print false
System.out.println(unique);
You can use below short and handy approach:
String a = "123452";
String[] split = a.split("");
List<String> list = Arrays.asList(a.split(""));
Set<String> set = new HashSet<>(list);
System.out.println("Unique: " + (list.size() == set.size()));
import java.util.*;
public class spnum
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number: ");
String num = sc.next();
int ctr = 0;
boolean isNumUnique = true;
for(int i = 0; i < num.length(); i++)
{
for(int j = 0; j < num.length(); j++)
{
if(num.charAt(i) == num.charAt(j))
{
ctr++;
}
}
if(ctr > 1)
{
isNumUnique = false;
}
ctr = 0;
}
if(isNumUnique == true)
{
System.out.println("Number is a unique number");
}
else
{
System.out.println("Number is not a unique number");
}
}
}
this code would give the right answer

StringIndexOutOfBoundsException Error

I'm new to JAVA and am working on a task to:
Take as input a user string
Take as input a user integer
Use the integer as an increment value
Return all character values in the string starting from 0 ending at the last character available after incrementing.
I'm getting correct results in terminal immediately followed by the dreaded StringOutOfBoundsException error. I'm not able to see where I am attempting to access a character in the string that is out of bounds and would be grateful for your expertise locating my error. Here is a snippet of my code:
import java.util.*;
public class EveryOtherCharacter
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
//initialize all variables to be used in this program
String userEntry;//store user word as a String
String error=("Invalid Entry!");//notify of error
String purpose=("Enter a word and an increment value and we'll\nreturn each character in your word using the number you provided".)
int increment;//store increment integer from user
int userEntryCount;//store total count of chars in userEntry
char value;//get character at increment value from userEntry
System.out.println("========================START PROGRAM=============================");
System.out.println(purpose);
System.out.println();//whitespace
System.out.print("Enter a word: ");
userEntry=input.nextLine();
userEntryCount = userEntry.length();
System.out.print("Enter an increment value: ");
increment=input.nextInt();
System.out.println();//whitespace
value=userEntry.charAt(0);
System.out.print(value);
for (int count=0; count <= userEntryCount; count++)
{
value=userEntry.charAt(increment);
userEntry=userEntry.substring(increment);
System.out.print(value);
}
if (increment > userEntryCount && increment <= 0)
{
System.out.println(error);
}
System.out.println();//whitespace
System.out.println("=========================END PROGRAM==============================");
}
}
Here is an example of what my terminal output looks like after running this program. Notice that the correct output is present immediately before the exception error:
java EveryOtherCharacter
========================START PROGRAM=============================
Enter a word and an increment value and we'll
return each character in your word using the number you provided
Enter a word: whyisthissohard
Enter an increment value: 3
wihsaException in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.charAt(String.java:658)
at EveryOtherCharacter.main(EveryOtherCharacter.java:57)
You're cutting through whyisthissohard by 3 each time. But you are looping through whyisthissohard's length in total.
for (int count=0; count <= userEntryCount; count++)
{
value=userEntry.charAt(increment);
userEntry=userEntry.substring(increment);
System.out.print(value);
}
First loop : value = 'i' ; userEntry = "isthissohard" ;
Second loop : value = 'h' ; userEntry = "hissohard";
Third loop : value = 's' ; userEntry = "sohard";
Fourth loop : value = 'a' ; userEntry = "ard";
Fifth loop => Error
I think when the instructions say "Use the integer as an increment value", you should be using it as an actual increment value like so.
public static void main(String[] args) {
String s = "whyisthissohard";
int skip = 3;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i += skip) { // <--- Increment value
sb.append(s.charAt(i));
}
//Return all character values in the string
System.out.println(sb.toString()); // wihsa
}
You could also print them all in the for-loop instead of adding to another string, if you want.
I ended up solving this using a while loop as follows:
while (n < length)//where n=userNumber & length=length of user word
{
character=userEntry.charAt(n);//character becomes the character of the word at the increment value
System.out.print(character);//print value of character at increment
userEntry=userEntry.substring(n);//set userEntry to value of new string starting at n
length = userEntry.length();//count the total number of characters in the new substring
}
After going through the logic of the for loop, I realized i had created and was trying to increment the value of i and that wasn't necessary. You all were a really big help in making think through the problem. I appreciate your help!

How to input a lot of data until you type in an invalid number in java

User inputs numbers one by one and then once they type in an invalid number (has to be from 1-200) the program calculates the average of the numbers that were inputted.
I'm just wondering what would the code be for this. I know the one for inputting one piece of data. Example would be:
`Scanner in = new Scanner(System.in);
String numberOfShoes = "";
System.out.println("Enter the number of shoes you want: (0-200) ");
numberOfShoes = in.nextLine();`
this is just an example, but this time I want the user to input a lot of numbers. I know I'm going to include a loop somewhere in this and I have to stop it once it contains an invalid number (using a try catch block).
* I would also like to add that once the user inputs another number it always goes to the next line.
Just use a while loop to continue taking input until a condition is met. Also keep variables to track the sum, and the total number of inputs.
I would also suggest having numberOfShoes be an int and use the nextInt() method on your Scanner (so you don't have to convert from String to int).
System.out.println("Enter your number of shoes: ");
Scanner in = new Scanner(System.in);
int numberOfShoes = 0;
int sum = 0;
int numberOfInputs = 0;
do {
numberOfShoes = in.nextInt();
if (numberOfShoes >= 1 && numberOfShoes <= 200) { // if valid input
sum += numberOfShoes;
numberOfInputs++;
}
} while (numberOfShoes >= 1 && numberOfShoes <= 200); // continue while valid
double average = (double)sum / numberOfInputs;
System.out.println("Average: " + average);
Sample:
Enter your number of shoes:
5
3
7
2
0
Average: 4.25
It added 5 + 3 + 7 + 2 to get the sum of 17. Then it divided 17 by the numberOfInputs, which is 4 to get 4.25
you are almost there.
Logic is like this,
Define array
Begin Loop
Accept the number
check if its invalid number [it is how u define a invalid number]
if invalid, Exit Loop
else put it in the array
End Loop
Add all numbers in your array
I think you need to do something like this (which #Takendarkk suggested):
import java.util.Scanner;
public class shoes {
public void main(String[] args){
int input = 0;
do{
Scanner in = new Scanner(System.in);
String numberOfShoes = "";
System.out.println("Enter the number of shoes you want: (0-200) ");
numberOfShoes = in.nextLine();
input = Integer.parseInt(numberOfShoes);
}while((input>=0) && (input<=200));
}
}
you can use for loop like this
for(::)
{
//do your input and processing here
if(terminating condition satisified)
{
break;
}
}

Easier way to guarantee integer input through Scanner?

For a program I am writing, I need to ask a user for an integer between 1 and 8. I've tried multiple (cleaner) ways of doing this but none of them worked, so I'm left with this:
int x = 0;
while (x < 1 || x > 8)
{
System.out.print("Please enter integer (1-8): ");
try
{
x = Integer.parseInt(inputScanner.next());
}
catch(NumberFormatException e)
{
x = 0;
}
}
Where inputScanner is a Scanner. Surely there is a better way?
Scanner does regular expressions, right? Why not check if it matches "^[1-8]$" first?
Using the nextInt() is already an improvement compare to simply using the next() method. And before that, you can use the hasNextInt() to avoid haing all this bunch of useless exceptions.
Resulting in something like this:
int x = 0;
do {
System.out.print("Please...");
if(scanner.hasNextInt()) x = scanner.nextInt();
else scanner.next();
} while (x < 1 || x > 8);
I had to do a graphic interface calculator (works only with Integers), and the problem was, that
the Tests didn't allow any Exceptions to be thrown if the input wasn't
Integer. So I couldn't use
try { int x = Integer.parseInt(input)} catch (Exception e) {dosomethingelse}
Because Java programs generally treat an input to a JTextField as a String
I used this:
if (input.matches("[1-9][0-9]*"){ // String.matches() returns boolean
goodforyou
} else {
dosomethingelse
}
// this checks if the input's (type String) character sequence matches
// the given parameter. The [1-9] means that the first char is a Digit
// between 1 and 9 (because the input should be an Integer can't be 0)
// the * after [0-9] means that after the first char there can be 0 - infinity
// characters between digits 0-9
hope this helps :)
You could try something like this:
Scanner cin = new Scanner(System.in);
int s = 0;
boolean v = false;
while(!v){
System.out.print("Input an integer >= 1: ");
try {
s = cin.nextInt();
if(s >= 1) v = true;
else System.out.println("Please input an integer value >= 1.");
}
catch(InputMismatchException e) {
System.out.println("Caught: InputMismatchException -- Please input an integer value >= 1. ");
cin.next();
}
}
Apache Commons is your friend. See NumberUtils.toInt(String, int)
String input;
int number;
while (inputScanner.hasNextLine())
{
input = inputScanner.nextLine();
if (input.equals("quit")) { System.exit(0); }
else
{
//If you don't want to put your code in here, make an event handler
//that gets called from this spot with the input passed in
try
{
number = Integer.parseInt(input);
if ((number < 1) || (number > 8))
{ System.out.print("Please choose 1-8: "); }
else { /* Do stuff */ }
}
catch (NumberFormatException e) { number = 0; }
}
}
I always like to pull in the full string so you can be sure that the user pushed the Enter button. If you just use inputScanner.nextInt() you can put two ints on a line and it will pull in one, then the other.
Example code:
int x;
Scanner in = new Scanner(System.in);
System.out.println("Enter integer value: ");
x = in.nextInt();
An array can also be used to store the integer.

Categories

Resources