How to allow multiple inputs from user in JOptionPane - java

Before I attempted to insert the Array the code was returning indivdual values for the year input but I would prefer if i could input a list and then display the list if it is a leap year. if it is not it should ignore it. I've not used arrays with JOptionPane... in actual fact I've never used arrays as this is my 4th week using java so I'm quite noobish. but definitely willing to take criticism and advice. I want to get better. Thanks in advance.
import javax.swing.JOptionPane;
public class SimpleMath {
public static int printLeap(int r, int k){
if((r % 4 == 0) && (r % 100 != 0) || (r % 400 == 0)){
return r;
}
else if ((r % 4 != 0) && (r % 100 == 0) || (r % 400 != 0));
return k;
}
public static void main(String[] args) {
while (true) { //while the statement is true (so it continues indefinitely until the break occurs).
String year = JOptionPane.showInputDialog("Enter input years to be tested, when done type End");
int year[] = new year[10];
for (int x=0; x<year.length; x++)
if ("End".equals(year)){ //if the user types End then the loop will break. it allows a string to be input for an int value
break;
} {
int r = Integer.parseInt(year);
int k = 0;
int i = printLeap(r, k);
if (i == 0) {
break; // or System.out.println("");
}
else
System.out.println("Leap years entered are: " + i + x);
}
}
}
}

So let's begin with some general code review items:
The code is not formatted well, which makes it hard to read. Fixing the indentation goes a long way toward making it readable for others.
The printLeap method accepts a parameter that you have called k. When you call your method you pass it the value 0 because you have initialized k to 0 and it never changes. So this forces me to ask - why is k a parameter if it never changes?
You have syntax errors in your code. This line: int year[] = new year[10]; is wrong - it should be written int[] year = new int[10]; but when this is fixed it creates a whole new problem which is duplicate variables. The array you declared conflicts with the String above: String year = JOptionPane.showInputDialog(...);
Later on in the code you try to parse the year as an integer, which you can't do because Integer.parseInt(...) takes a String as a parameter not an array.
Variable names are too short and have no meaning. Variables with single character names like r, k, i are in most situations not a good idea. In general the only time it's considered acceptable to use a single character name for a variable is inside of a for loop definition like: for(int i=0; i<10; i++) because this is such a common pattern.
As for your question, it's not entirely clear what you're really asking here. It sounds like you want to accept a list of years as an input and output the years that are leap years.
So I'll help you get started by providing the following code:
//Accept input from the user - a single String containing multiple years separated by commas.
String input = JOptionPane.showInputDialog("Enter years to be tested (comma separated): ");
//Split the String by commas and store the resulting individual years in an array
String[] yearArray = input.split(",");
//Process each year in the array
for(String year: yearArray){
int intYear = Integer.parseInt(year);
System.out.println("Here's the integer value: " + intYear);
//Do more logic here...
}
Hope this helps!

Related

Keep getting the error For input string:"" in my code [duplicate]

This question already has answers here:
What's the difference between next() and nextLine() methods from Scanner class?
(15 answers)
Closed 2 years ago.
I keep getting this error on my code. I think its to do with my parseInt() command but im not sure. Im trying to create a stack of integers that come from a user input string such as "PUSH 5" and just extract the 5 from the string to push into the stack.
import java.util.*;
public class lab6
{
public static void main(String []args)
{
Scanner sc = new Scanner(System.in);
int size = sc.nextInt();
lab6stack theStack = new lab6stack(size);
String [] ar = new String [size];
for(int i = 0; i < size; i++)
{
ar[i] = sc.next();
if(ar[i].charAt(1) == 'U')
{
String sub = ar[i].substring(4);
int num = Integer.parseInt(sub);
theStack.push(num);
}
else if(ar[i].charAt(1) == 'O')
{
theStack.pop();
}
}
while (!theStack.isEmpty())
{
System.out.println(theStack.pop());
}
}
}
As others have said, sc.next() only returns "PUSH", not "PUSH 5". In my opinion, #Pshemo's solution works just fine, but you said that it is not how you want to do it. In that case, you can replace your sc.next() with sc.nextLine() to get "PUSH 5". That way, you can keep the rest of your code the same.
Hope this is what you want!
You're referring to the space between PUSH and your number in this line:
String sub = ar[i].substring(4);
As substrings also start counting on zero, your number should be parsed when using substring(5); here instead.
Here is an example with indexes:
"P"=0 ; "U"=1 ; "S"=2 ; "H"=3 ; " "=4 ; "3"=5
This is because you are not checking the length of the string before grabbing the character.
here:
if(ar[i].charAt(1) == 'U')
and here:
else if(ar[i].charAt(1) == 'O')
Check with ar[i].length() >= 1. For example:
if(ar[i].length() >= 1 && ar[i].charAt(1) == 'U')
You will also need to apply the other two fixes addressed in the other answers.
Use sc.nextLine() when reading the input and use substring(5) in the "PUSH" if case.

StringBuilder.insert() not changing output

I'm trying to make a short program that converts any string into T H I S F O N T.
For example: "This is a test sentence" turns into "T H I S I S A T E S T S E N T N C E"
I have a StringBuilder inside a while loop, but using finale.insert(i, '\t'); doesn't work.
import java.util.Scanner;
public class Executable {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String x;
int i = 0;
System.out.print("Input text here: ");
x = input.nextLine();
StringBuilder finale = new StringBuilder(x.toUpperCase());
while(i > finale.length()) {
if(finale.substring(i, i) == " ") {
i += 2;
finale.insert(i, '\t');
}
}
System.out.println(finale);
}
}
Any help?
You have a few issues with your code. Before I present an implementation that works, let's look at those other issues.
Your while loop checks if i > finale.length(). Since i = 0 the while loop never has a chance to begin.
You are comparing strings using == and this is not correct. == is used to confirm two objects are equal, not the value of two strings. You would need to use string.equals() instead.
You're doing too much in your loop anyway. Using a simple for loop can accomplish the goal quite simply.
Here is a new loop you can use instead of what you have:
for (int i = 1; i < finale.length(); i++) {
finale.insert(i++, " ");
}
The output: T H I S F O N T
For those unfamiliar with for loops, here's a very simple breakdown of how the above is structured.
The for loop is defined in three parts:
for (variable_to_increment; repeat_until_this_condition_is_met; modify_variable_on_each_iteration) {
// Code to be executed during each pass of the loop
}
First, we define a variable that we can track on each loop: int i = 1. By setting i = 1, we are going to skip the first character in the string.
The next statement, i < finale.length() means that we want to keep repeating this loop until we reach the length of our string. For example, if the string is 5 characters long and we've run the loop 4 times, i now equals 5 and is no longer less than the string's length, so the loop ends.
The last part is i++. This tells Java what we want to do with i after each loop. In this case, we want to increment the value by 1 each time the loop repeats.
Everything inside the brackets is, obviously, the code we want to execute on each loop.
You're saying while i>finale.length() but i is initialized as 0. You never enter the while loop.
Some issues with your code (see inline comments):
import java.util.Scanner;
public class Executable {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String x;
int i = 0;
System.out.print("Input text here: ");
x = input.nextLine();
StringBuilder finale = new StringBuilder(x.toUpperCase());
while(i > finale.length()) { // this condition is incorrect. Initially
// this condition will always be false
// if you input some sentence. It should be
// i < finale.length()
if(finale.substring(i, i) == " ") { // here preferably you should use
// equals method to compare strings
i += 2;
// you are only incrementing the i if the ith
// substring equals " ". Firstly, substring(i,i)
// will return empty string because the second argument
// is exclusive
finale.insert(i, '\t');
}
}
System.out.println(finale);
}
}
If you want to have an alternate method (not very optimal) for doing what you want to do, you can try the following approach:
import java.util.Scanner;
public class Executable {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String x;
int i = 0;
System.out.print("Input text here: ");
x = input.nextLine();
String finale = x.toUpperCase().replaceAll(" ","").replaceAll("", " ");
System.out.println(finale);
}
}
First, convert the string to uppercase --> then remove all spaces between the words --> then insert spaces between all letters. The code line which does this is,
String finale = x.toUpperCase().replaceAll(" ","").replaceAll("", " ");
Here is a sample run:
Input text here: This is a sentence
T H I S I S A S E N T E N C E
The correct way with your method would be, just increment until you have twice the size of the initial String
while (i < x.length() * 2) {
finale.insert(i, '\t');
i += 2;
}
An easier way would be with a classic for-loop:
StringBuilder finale = new StringBuilder();
for (char c : x.toUpperCase().toCharArray()) {
finale.append(c).append('\t');
}
Use a for loop since you know the number of iterations:
Scanner input = new Scanner(System.in);
String x;
System.out.print("Input text here: ");
x = input.nextLine();
StringBuilder finale = new StringBuilder(x.toUpperCase());
int len = finale.length();
for (int i = 1; i < 2 * len; i+=2 ) {
finale.insert(i, '\t');
}
System.out.println(finale);
You are comparing strings with ==. Never do that; use equals instead.
For future readers: this job can be done elegantly using Java 8 Streams:
String result = str.chars()
.filter(i -> i != ' ')
.mapToObj(t -> (char) t)
.map(Character::toUpperCase)
.map(Character::valueOf)
.collect(Collectors.joining(" ");

Why is this method returning 0 no matter what the user inputs are?

The method CountQiftPositiv is returning 0 no matter what inputs I type. What am I doing wrong here?
import java.util.Scanner;
public class QiftPositivCount
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
final int SENTINEL = -9999;
int x = 0;
int count = 0;
do
{
System.out.print("Type numbers (-9999 to end) : ");
x = scan.nextInt();
if(x == SENTINEL)
{
break;
}
count++;
}while (x != SENTINEL);
if(count == 0)
{
System.out.println("You didnt type any number");
}
else
{
System.out.println("There are " + count + " numbers typed , and the numbers that fulfill the conditon are "
+ CountQiftPositiv(x));
}
}
private static int CountQiftPositiv(int nr)
{
int poz = 0;
if(nr % 2 == 0 && nr % 3 == 0 && nr > 0)
{
poz++;
}
return poz;
}
}
Your do-while loop throws out all user input except the last integer entered (if any). Since the only way out of that loop (not counting exceptions) is the sentinel value -9999, that is the only value you will ever assign to x and pass to CountQiftPositiv.
CountQiftPositiv, meanwhile, only returns 1 if for positive integers divisible by 6. For every other value, including your sentinel, it returns 0.
Other Sentinel Problems
The use of a sentinel value is almost always a mistake (unless that's specifically part of your assignment). Sooner or later, that "impossible" input will actually show up.
Since your goal is to continue the loop until the user is done (a "yes or no" question), use a local Boolean variable, and test that. Also, java.util.Scanner has lots of useful methods for exactly this kind of situation, for example:
boolean done = false;
while (! done) {
if (scan.hasNextInt()) {
// Store scan.nextInt() for use later. See below.
} else {
// No more (valid) inputs.
done = true;
}
}
This loop could actually be shortened to just while (scan.hasNextint()) { ... }, but storing your loop's continue-or-end condition in a variable is handy for more complex exit decisions.
Storing User Input
You aren't storing more than one user input, ever. Create a List of some sort to store them, and then operate on that list.
java.util.List<Integer> numbers = new java.util.LinkedList<Integer>();
Later, in the "while not done" loop:
if (scan.hasNextInt()) {
numbers.add(scan.nextInt());
} else {
done = true;
}
Counting User Inputs
No need for count --- your collection of integers will store that for you:
if (numbers.size() == 0) {
System.out.println("You didn't type any numbers!");
}
Printing Output
Finally, output each number only if it fulfills that weird condition. This assumes you rewrite CountQiftPositiv to return a boolean (which it almost does already):
for (int number : numbers) {
if (CountQiftPositiv(number)) {
System.out.println(number);
}
}
You'll probably want to rename that method now that it no longer counts anything.
I leave the rest to you.
PS: It's almost always a good idea to separate input, processing, and output into (at least) three different methods, especially when you're learning. It's vastly easier to understand a bunch of short methods than one do-it-all method, and makes debugging problems like this much easier.
You have return 0 because last input is -9999 a negative number, and this condition if(nr % 2 == 0 && nr % 3 == 0 && nr > 0) is usually false.
Try to change the SENTINEL nymber:
You're using CountQiftPositiv(x) outside of the while loop.
With the code you have, it's the same thing as you call CountQiftPositiv(-9999)
I'm suggesting you to do something like:
do {
System.out.print("Type numbers (-9999 to end) : ");
x = scan.nextInt();
if(x == SENTINEL) {
break;
}
if (CountQiftPositiv(x) > 0) {
count++;
}
} while (x != SENTINEL);
I suggest also to rework your loop since the break is not required if you use the x = scan.nextInt(); wisely.
CountQiftPositiv(x) sends -9999 in because its the last x value always -> as you stop taking inputs when x = -9999
nr < 0 -> poz will stay at 0
I've made a temp variable which will take your input, if the input is not equal to the SENTINEL variable, it will set x = temp thus removing the -9999 value from being passed into CountQiftPositiv().
Also when you are checking for a number that is a factor for multiple numbers, all you have to do is multiply the numbers together and check the mod for that number.
For 2 and 3, all you have to check is 6.
import java.util.Scanner;
public class QiftPositivCount {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
final int SENTINEL = -9999;
int temp;
int x = 0;
int count = 0;
do {
System.out.print("Type numbers (-9999 to end) : ");
if((temp = scan.nextInt()) == SENTINEL){
break;
}else {
x = temp;
count++;
}
} while (temp != SENTINEL); // not really needed as you have the break statement
if (count == 0) {
System.out.println("You didnt type any number");
} else {
System.out.println("There are " + count + " numbers typed , and the numbers that fulfill the conditon are "
+ CountQiftPositiv(x)); // This was sending -9999 which will always evaluate to false in the function
//poz will stay at 0 the entire time
}
}
private static int CountQiftPositiv(int nr) {
int poz = 0;
//if(nr % 6 && nr > 0){
if (nr % 2 == 0 && nr % 3 == 0 && nr > 0) {
poz++;
}
return poz;
}
}

Creating a loop to check array (java)

Homework assignment Suggestions only please as I wish very much to learn this as second nature!
The goal is to create an array with a user specified question amount (array size) followed by an answer key (said array size now filled). Then to have the user input the "students" answers to check against key.
I wrote all that no worries. Works lovely. The issue I am having is in two areas:
Create a loop that asks to grade another quiz.
Have it only check/score/calculate every other answer. ie: even answers only.
I have used a do/while loop to continue checking but couldn't get a sentinel value to stick. Also depending on where I placed it, the answers kept coming up as the first check. So I am unsure as to where to place and how to write it. I even tried to use a for loop boxing in the array and student answer portion to no avail.
As regards to having it check every other one, I thought of modifying the count of "i" to something like ((i+1)*2) instead of i++ for the two for loops but I just get errors as that seems to not be proper at all.
Thank you in advance!
import java.util.Scanner;
import java.text.NumberFormat;
public class EvenQuizzes {
public static void main(String[] args) {
int quizQuest = 0, count = 0;
double percentTotal = 0.0;
Scanner scan = new Scanner(System.in);
System.out.print("How many questions are in the quiz? Or enter 0 to quit. ");
quizQuest = scan.nextInt();
int[] answers = new int[quizQuest]; // scan in question total and apply
// to array
System.out.println("Enter the answer key: ");
for (int i = 0; i < answers.length; i++) {
answers[i] = scan.nextInt();
}
for (int i = 0; i < answers.length; i++) {
System.out.println("Enter the answer to be graded : ");
int toGrade = scan.nextInt();
if (toGrade == answers[i]) {
count++;
}
}
percentTotal = ((double) count / quizQuest);
NumberFormat defaultFormat = NumberFormat.getPercentInstance();
defaultFormat.setMinimumFractionDigits(2);
System.out.println("The questions answered correctly total: " + count);
System.out.println("The percentage correct is: " + defaultFormat.format(percentTotal));
System.out.println("\nAnother quiz to be graded?");
}
}
// do ( quizQuest != 0){ //condition check to run new quiz against KEY
// for (int j = 0; (quizQuest = scan.nextInt()) != 0; j++); {
At the bottom is what I had considered for the loop portion I am having trouble with.
As you asked for hints (and not the code), here it is:
For more than one quizzes, use do-while, as follows:
do{
//do something
//scan the value of quiz quest
//do something
}while(quizquest != 0)
Now, if only answers at even positions are to be checked, do following:
for (int i =0; i <answers.length; i++)
{
System.out.println("Enter the answer to be graded : ");
int toGrade = scan.nextInt();
if(i % 2 == 0 && toGrade == answers[i]){
count++ ;
}
}
Create a loop that asks to grade another quiz: You could use a do-while loop with a boolean indicating if the user (teacher?) wants to grade another quiz:
do{
boolean continue = false;
// check if the user wants to continue
while(continue);
Have it only check/score/calculate every other answer. ie: even answers only: You can check for even answers with the modulo operator:
if(i % 2 == 0){
// even answer
}
Hope this helps!
You should have a variable, perhaps named continue, whose default value is 'Y'. At the very beginning, create a while loop that checks the condition continue==Y, and at the end when you ask "Another quiz to be graded?", read in the input to the variable continue.

string index out of range: 7 error

Hello I'm writing a code that asks the user for a tweet then tells the user if the tweet is the correct length and how many #'s #'s and links that are in it but everytime I run this I get the error string index out or range: 7. Any ideas?
import java.util.Scanner;
import java.lang.Math;
class Main {
public static void main(String[] args)
{
Scanner scan = new Scanner (System.in);
System.out.println ("Please enter a tweet: ");
String tweet = scan.nextLine();
int hashtags = 0;
int attributions = 0;
int links = 0;
if (tweet.length() > 140) {
int excess = tweet.length()-140;
System.out.println ("Excess Characters: " + excess);
} else {
System.out.println ("Length Correct.");
while (tweet.length() <= 140) {
if (tweet.charAt(0) == '#'){
hashtags ++;
}
if (tweet.charAt(0) == '#'){
attributions ++;
}
if (tweet.substring(0,8) == "http://") {
links ++;
}
tweet = tweet.substring(1);
}
System.out.println ("Number of Hashtags: " + hashtags);
System.out.println ("Number of Attributions: " + attributions);
System.out.println ("Number of Links: " + links);
}
}
}
Two problems, at least. The first is that you should not use substring on a string that's too short. It's far better to use String.startsWith:
if (tweet.startsWith("http://")) ...
so that you don't have to even worry about the length of the string, or getting your character count wrong, or having it fail because you used == rather than String.equals() :-)
Secondly, regarding the following code:
while (tweet.length() <= 140) {
:
tweet = tweet.substring(1);
}
That's going to keep going once your string is empty, simply because zero (and every negative number for that matter) is less than 140.
And, of course, doing something like tweet.charAt(0) on an empty string is going to give you a bit of a problem, similar to your use of substring. You need to re-examine your terminating condition for the loop, making it something like:
while (tweet.length() > 0) {
The first problem is that you're trying to get an 8-length substring of the tweet string without knowing how long the tweet is. What if the tweet is only 6 characters? If it is, you get an index out of bounds exception because you're looking two indices past where the array ends.
You should add a conditional guard:
if (tweet.length() >= 8 && tweet.substring(0,8).equals("http://")) {
links++;
}
The && operator means that tweet.substring() will never be checked if the length of the string is less than 8, so you avoid stepping out of bounds.
The second problem is that, even once you add that condtional guard, what you're doing doesn't make any sense. The length of the string returned by substring(beginIndex, endIndex) is equal to endIndex - beginIndex, or 8 in this case. The string "http://" is only seven letters, so it's logically impossible for an 8-character string to ever equal it. Use the startsWith() function instead of substring from the 0 position:
The line from before should look like so:
if (tweet.startsWith("http://")) {
links++;
}
You should definitely use a for loop instead:
String string= "hello";
for (int i = 0; i < string.length(); ++i)
{
if (string.charAt( i ) == '#')
{
//do something
}
}
That will insure that you traverse the entire string correctly.
Secondly, you need to make sure that the substring(0, 8) is inbounds before you assume. That is probably what's causing your error in some test cases.

Categories

Resources