Ok, I posted once earlier but it was locked due to not demonstrating a basic understanding, and the answers I did get before it was locked didn't help me. I'm at a super beginner level of java and this is what I want my program to do (will post code at end). I want the user to input anything they want. Then, if it is not a number, I want it to display that they need to input a number. Then, after they input a number, I want it to display whether or not that number is even or odd. I read about parseInt and parseDouble but i can't figure out how to get it to work how I want. I am not sure any more if parsing is what i want to do. I dont want to instantly convert it to numbers, just to check if it IS a number. then i can proceed to do things after the program has determined if it is a character or number. thanks for any help and let me know if you need more information!
ok i changed some things and used a lot of code from no_answer_not_upvoted. here is what i have now. it runs fine and works with negative and positive whole numbers as specified in the directions. the only thing that bugs me is after all is said and done, i get this error in the compile box at the bottom of eclipse. the program does what is intended and stops appropriately but i dont understand why i am getting this error.
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1585)
at monty.firsttry2.main(firsttry2.java:21)
public static void main(String[] args) {
System.out.print("Enter a character or number. This program will run until you enter a whole number, then it will"
+ "tell you if it was even or odd.");
while (true) {
Scanner in=new Scanner(System.in);
int num;
while(true) {
String input=in.nextLine();
try {
num=Integer.parseInt(input);
break;
}
catch (NumberFormatException e) {System.out.print("That wasn't a whole number. Program continuing.");}
}
if (num==0) {System.out.print("Your number is zero, so not really even or odd?");}
else if (num%2!=0){System.out.print("Your number is odd.");}
else {System.out.print("Your number is even");}
in.close();
}
}
}
Assumption
A String is to be considered a number if it consists of a sequence of digits (0-9), and no other characters, except possibly an initial - sign. Whereas I understand that this allows Strings such as "-0" and "007", which we might not want to consider as numbers, I needed some assumptions to start with. This solution is here to demonstrate a technique.
Solution
import java.util.Scanner;
public class EvensAndOdds {
public static final String NUMBER_REGEXP = "-?\\d+";
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
for(;;) { // Loop forever
System.out.println("Enter a number, some text, or type quit");
String response = input.nextLine();
if (response.equals("quit")) {
input.close();
return;
}
if (response.matches(NUMBER_REGEXP)) { // If response is a number
String lastDigit = response.substring(response.length() - 1);
if ("02468".contains(lastDigit)) {
System.out.println("That is an even number");
} else {
System.out.println("That is an odd number");
}
} else {
System.out.println("That is not a number");
}
}
}
}
Justification
This solution will match a number of ANY length, not just one that will fit into an int or a long; so it is superior to using Integer.parseInt or Long.parseLong, which both fail if the number is too long. This approach can also be adapted to more complicated rules about what constitutes a number; for example, if we decided to allow numbers with comma separators (such as "12,345" which currently will be treated as not a number); or if we decided to disallow numbers with leading zeroes (such as "0123", which currently will be treated as a number). This makes the approach more versatile than using Integer.parseInt or Long.parseLong, which both come with a fixed set of rules.
Regular expression explanation
A regular expression is a pattern that can be used to match part of, or all of a String. The regular expression used here is -?\d+ and this warrants some explanation. The symbol ? means "maybe". So -? means "maybe a hyphen". The symbol \d means "a digit". The symbol + means "any number of these (one or more)". So \d+ means "any number of digits". The expression -?\d+ therefore means "an optional hyphen, and then any number of digits afterwards". When we write it in a Java program, we need to double the \ character, because the Java compiler treats \ as an escape character.
There are lots of different symbols that can be used in a regular expression. Refer to http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html for them all.
this shows you how to do it
import java.util.Scanner;
public class EvenOdd {
public static void main(String[] args) {
System.out.print("Enter a character or number. Seriously, though, it is meant to be a number, but you can put whatever you want here. If it isn't a number however, you will get an error message.");
try (Scanner in = new Scanner(System.in)) {
int n;
while (true) {
String input=in.nextLine();
try {
n = Integer.parseInt(input);
break;
} catch (NumberFormatException e) {
System.out.println("you did not enter just an integer, please try again");
}
}
if (n % 2 == 0) {
System.out.println(n + " is even");
} else {
System.out.println(n + " is odd");
}
}
}
}
As is already mentioned in other answers, you will need to call parseDouble statically with
Double theNumber = Double.parseDouble(numberString);
Next you will want to look at wrapping this in a try/catch so that you can do the even/odd check if theNumber is created or set the error message if an exception is caught.
Since you are a beginner, you need to understand the difference between numbers (integers, double, strings, characters), so the following will guide you.
First, read input one line at a time,
Java read line from file)
Then scan line looking for characters that form what you consider to be an integer (allow leading spaces?, then '+' or '-', then digits 0-9, and then trailing spaces.
Here are the rules (for integers)
leading spaces ok (this is up to you) (how: How to check if a char is equal to an empty space?)
optional single '+' or '-'
one or more digits (how: How to check if a character in a string is a digit or letter)
optional trailing space(s) (again, this is up to you)
Anything other than this pattern violates the test for 'is this an integer'. Btw, Double is an extended precision real number.
import java.lang.*;
import java.util.Scanner;
public class read_int
{
public static boolean isa_digit(char ch) {
//left as exercise for OP
if( ch >= '0' && ch <= '9' ) return true;
return false;
}
public static boolean isa_space(char ch) {
//left as exercise for OP
if( ch == ' ' || ch == '\t' || ch == '\n' ) return true;
return false;
}
public static boolean isa_integer(String input) {
//spaces, then +/-, then digits, then spaces, then done
boolean result=false;
int index=0;
while( index<input.length() ) {
if( isa_space(input.charAt(index)) ) { index++; } //skip space
else break;
}
if( index<input.length() ) {
if( input.charAt(index) == '+' ) { index++; }
else if( input.charAt(index) == '-' ) { index++; }
}
if( index<input.length() ) {
if( isa_digit(input.charAt(index)) ) {
result=true;
index++;
while ( isa_digit(input.charAt(index)) ) { index++; }
}
}
//do you want to examine rest?
while( index<input.length() ) {
if( !isa_space(input.charAt(index)) ) { result=false; break; }
index++;
}
return result;
}
public static void main(String[] args) {
System.out.print("Enter a character or number. Seriously, though, it is meant to be a number, but you can put whatever you want here. If it isn't a number however, you will get an error message.");
Scanner in=new Scanner(System.in);
String input=in.nextLine();
if( isa_integer(input) ) {
System.out.print("Isa number.");
}
else {
System.out.print("Not a number.");
}
}
}
Related
Example output
file1.txt contents
I have to do a project to determine whether user input is a Palindrome (same letters forwards as backwards). I must create a menu and the user selects whether to input through the console or through a file. I had no issue with reading from the console. I am having trouble producing the correct output through reading Files however.
For a file to be a palindrome, the whole file must be able to be read forwards and backwards and be equal. Then the file contents must be printed and labeled as a Palindrome. I am able to determine if a string is a palindrome within the file, but not the whole file itself. I tried to use .hasNextLine() and compare the lines, but the output is not exactly what is desired.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;
public class PalindromeMachine { //begin class
public static void main(String[] args) { //begin main
boolean choice1 = false;
boolean choice2 = false;
boolean choice3 = false;
while (choice3 == false) {
//create a menu
System.out.println("Welcome to the Palindrome Machine!");
for (int i = 0; i < 35; i++) {
System.out.print("-");
}
System.out.printf("\n1. Read one word from the keyboard");
System.out.printf("\n2. Read one or more words from a file");
System.out.printf("\n3. Exit");
System.out.printf("\nEnter your selection: ");
//gather user input
Scanner user = new Scanner(System.in);
try {
int num = user.nextInt();
if (num > 3 || num < 1) {
System.out.println("Invalid menu option");
}
if (num == 1) {
choice1 = true;
}
if (num == 2) {
choice2 = true;
}
if (num == 3) {
choice3 = true;
}
} catch (InputMismatchException e) {
System.out.println("Invalid menu option");
}
//based on user selection, read in the word or read in lines from a file
while (choice1 == true) {
System.out.printf("Enter the word you would like to check: ");
String checkThis = user.next();
int front = 0;
int back = checkThis.length() - 1;
while (front < back) {
if (checkThis.charAt(front) != checkThis.charAt(back)) {
choice1 = false;
System.out.printf("%s: this word is not a palindrome\n\n", checkThis);
}
front++;
back--;
}
if (choice1 == true) {
System.out.printf("%s: this word is a palindrome\n\n", checkThis);
choice1 = false;
}
} //end while for choice 1
//read from file and determine if palindrome
while (choice2 == true) {
System.out.printf("Enter the file you would like to check: ");
String name;
name = user.nextLine();
try {
File pali = new File(name);
Scanner userRead = new Scanner(pali);
while (userRead.hasNextLine()) {
String checkThis = userRead.nextLine();
//palindrome info
int front = 0;
int back = checkThis.length() - 1;
while (front < back) { //palindrome
if (checkThis.charAt(front) != checkThis.charAt(back)) {
choice2 = false;
System.out.printf("\n%s: this file is not a palindrome",
checkThis);
}
front++;
back--;
} //end palindrome
if (choice2 == true && userRead.hasNextLine() != false) {
System.out.printf(checkThis
+ ": this file is a palindrome\n");
choice2 = false;
} else {
System.out.println("");
System.out.printf(checkThis);
}
} //end of while the file has text
} catch (FileNotFoundException e) {
System.out.printf("\nInvalid file");
}
} // end choice 2
//loop until the user exits + catch inputmismatch
} // end while it loop until exit
} //end main
} //end class
If your intent is to read the entire file and then check if the entire contents are a palindrome or not, then lines in general are a bit of a complicated mess.
Is:
Hello, there!
!ereht ,olleH
A palindromic file? Note that it ends in a newline, so if you attempt to compare byte-for-byte, it's not. If the intent is that it is supposed to 'count', then presumably you'd first trim (lop any whitespace off of the front and back of the entire thing) and then compare byte-for-byte?
If the file's encoding involves characters smearing out over bytes (common - UTF_8, the most common encoding, can do that for any character that isn't simple ASCII), byte-for-byte fails immediately, so I guess character-by-character? Java's 'character' is actually part of surrogate pairs, so symbols from the higher unicode planes, such as emoji, will thus immediately cause trouble (as the emoji is two characters, and therefore won't be the same backwards and forwards). Just go with 'eh, whatever, no files will contain emoji'? Or try to compare codepoints instead?
What about commas, capitals, and other symbol characters? Is this:
Hello, there!
Ereht, olleh!
supposed to 'count'? If you look at Just the actually letters and forget about casing, it is. But a char-by-char comparison will obviously fail. Before you say: That's not palindromic, the usual "A man, a plan, a canal, Panama!" requires that you disregard non-letters and disregard casing.
In any case, it all starts with reading the entire file as a string; Scanner is designed to read tokens (tokens are the things in between the separator), and it has some ugly misplaced baggage in the form of the nextLine() method that you probably shouldn't be using. In any case, it can't read the entire file in one go which makes this vastly more complicated than it needs to be, so step 1 is do not use it.
There's the new file API which is great for this:
import java.nio.file.*;
Path p = Paths.get(fileName);
String contents = Files.readString(p);
That will read the entire contents. We can then remove everything that isn't a letter from it:
contents.toLowerCase().replaceAll("[^a-z]", "");
That thing is a 'regular expression' which is a mini language for text manipulation. [^...] is 'match any character that isn't mentioned here', and a-z is naturally, everything from a to z. In other words, that says: Take the input, lowercase everything, then replace all non-letters with blank, thus giving you only the letters. I turns "A man, a plan, a canal, Panama!" into "amanaplanacanalpanama".
It even gets rid of newlines entirely.
Now you can use the principle at work in your code (start from the beginning and end, fetch the characters there, compare them. If not equal - it is not a palindrome. If equal, increment your 'front pointer', decrement your 'back pointer', and keep going with the comparisons until your pointers are identical, then it is a palindrome.
Scanner has only two uses:
Keyboard input. In which case you should never use .nextLine() (nextLine is broken. It does what the javadoc says it does, which not what anyone expects, hence, do not use it for this) - and always call .useDelimiter("\\R") immediately after making the scanner. This configures it the way you'd expect. Use .nextX() calls to fetch info. next() for strings .nextInt() for integers, etc. All next calls will read entire lines.
Tokenizing inputs. This is only useful if the input is defined in terms of tokens separated by separators. Only a few formats follow that kinda rule. Even your usual 'CSV' files don't, not really - you need custom CSV parsers for that.
"Read an entire file to see if it is palindromic" fits neither use.
Write a program that asks a user to input a string. Then asks a user to type in an index value(integer). You will use the charAt( ) method from the string class to find and output the character referenced by that index. Allow the user to repeat these actions by placing this in a loop until the user gives you an empty string. Now realize that If we call the charAt method with a bad value (a negative value or a integer larger than the size of the string) an exception will be thrown. Add the code to catch this exception, output a warning message and then continue with the loop
import java.util.Scanner;
class Main
{
public static void main(String[] args)
{
System.out.println("");
String s;
int ind;
Scanner sc=new Scanner(System.in);
while(sc.hasNext())
{
s=sc.next();
if(s.length()==0)
break;
ind=sc.nextInt();
try {
char ch=s.charAt(ind);
System.out.println("Character is "+ch);
}
catch(Exception e) {
System.out.println("Bad index Error!");
}
}
}
}
Yes. You could rely on assignment evaluating to the assigned value. Also, call Scanner.hasNextInt() before calling Scanner.nextInt(). Like,
System.out.println();
String s;
Scanner sc = new Scanner(System.in);
while (sc.hasNext() && !(s = sc.next()).isEmpty()) {
if (sc.hasNextInt()) {
int ind = sc.nextInt();
try {
char ch = s.charAt(ind);
System.out.println("Character is " + ch);
} catch (Exception e) {
System.out.println("Bad index Error!");
}
}
}
There is a bug; sc.next() cannot return an empty string in this code. Try editing it this way:
while(sc.hasNext()) {
s = sc.next();
if(s.length() == 0) {
System.out.println("Woah, Nelly!");
break;
}
// ...
}
See if you can get the program to print "Woah, Nelly!" by entering a blank line, or anything else. I can't, and assuming I understand the documentation correctly, it is impossible for the if condition to ever be true here (emphasis mine):
Depending upon the type of delimiting pattern, empty tokens may be returned. For example, the pattern "\\s+" will return no empty tokens since it matches multiple instances of the delimiter. The delimiting pattern "\s" could return empty tokens since it only passes one space at a time.
This pattern "\\s+" is the default one, and you haven't set a different one, so your scanner should never return an empty token. So the strict answer to "is there a way to write this program without the break statement?" is: yes, you can just delete the if(...) break; code and it doesn't change the behaviour in any way.
However, that's not really a solution to your problem because it doesn't give the user a way to exit the program. You should use nextLine() instead of next() to allow reading a blank line from the user.
I'm currently working on a small project for an introductory java class. We're supposed to make a program which can take in an integer from the user and output the number of odds, evens, and zeroes present within the code. This seemed pretty easy to me, and I managed to implement the code, but a class mate, after I criticized his code for incorrectly following the prompt, noted that my code would crash if anything but digits was input.
Out of spite I've tried to go beyond the prompt and have the program output an error message if it encounters characters aside from digits (instead of having my compiler return an error). However I'm returning multiple errors within the Eclipse compiler when using the isDigit method in the Character class.
I don't know exactly what's causing this, and I feel I must be missing something crucial, but my teacher quite frankly isn't qualified enough to understand what's causing the error, and none of my classmates can seem to figure it out either.
package ppCH5;
import java.util.Scanner;
public class PP5_3
{
public static void main(String[]args)
{
int even = 0;
int odd = 0;
int zero = 0;
int num = 0;
int count = 0;
boolean inputError = false;
System.out.println("please provide some integer");
Scanner scan = new Scanner(System.in);
String numbers = scan.next();
scan.close();
Scanner intSeperate = new Scanner(numbers);
intSeperate.useDelimiter("");
while(intSeperate.hasNext())
{
if(Character.isDigit(numbers.charAt(count)))
{
count++;
num = intSeperate.nextInt();
if((num % 2)==1)
odd++;
if((num % 2)==0)
if(num==0)
zero++;
else
even++;
}
else
{
count++;
inputError = true;
}
}
intSeperate.close();
if(!inputError)
{
System.out.println("There are " + even + " even digits.\n" + odd + " odd digits.\nAnd there are " + zero + " zeros in that integer.");
}
else
{
System.out.println("You have provided a disallowed input");
}
}
}
Any help would be appreciated, I'm currently at a loss.
When you enter a single non-digit character, say a, the else branch inside the while loop will get executed, incrementing count, right? And then the loop will start a new iteration, right?
In this new iteration, intSeparator.hasNext() still returns true. Why? Because the input a is never read by the scanner (unlike if you have entered a digit, intSeparator.nextInt would be called and would have consumed the input).
Now count is 1 and is an invalid index for the 1-character string. Therefore, numbers.charAt(count) throws an exception.
This can be avoided if you break; out of the loop immediately in the else block:
else
{
inputError = true;
break;
}
Also, don't close the scan scanner. scan is connected to the System.in stream. You didn't open that stream, so don't close it yourself.
Ok, so my computer teacher has asked us to make a simple game that asks the user to guess a radomly generated number, but I want to take it one step further and make it so that it display error messages when the user tries certain things. The problem here is that I am new to booleans and well, I am having a bit of trouble using java.util.Scanner and booleans. So, if anyone could take a quick look at this I would appreciate it.
import java.util.Scanner;
import java.util.Random;
public class MoreGuessing{
//Instantiation
Scanner reader = new Scanner(System.in);
Random number = new Random();
//Variables
int randomnumber = number.nextInt(10) + 1;
int cntr = 1;
static String decimalguessed;
String error1 = "Error001: Decimal found, please enter a whole number between 1-10." + "\n" + "Program terminated......";//Decimal portion error.
String error2 = "Please enter a positive number." + "\n" + "Program terminated......"; //Negative number error.
String error3 = "Unknown character entered." + "\n" + "Program terminated......"; //Unknown character error.
//Verifier
public static boolean verifyLetters() {
if (decimalguessed.matches("[a-zA-Z]+")){
return true;
}else{
return false;
}
}
public static void main(String [] args){
//Input and display
System.out.print("Please enter a whole number between 1-10: ");
decimalguessed = reader.nextLine();
//Process and Errors
while (decimalguessed != randomnumber) {
if (verifyLetters() != false){
System.out.println(error3);
System.exit(1);}
if (decimalguessed % 1 != 0) {
System.out.println(error1);
System.exit(1);}
if (decimalguessed < 0) {
System.out.println(error2);
System.exit(1);}
if (randomnumber != decimalguessed){
System.out.println("You've lost, please make another attempt.");}
System.out.print("Please enter a whole number between 1-10: ");
decimalguessed = reader.nextDouble();
cntr++;
}
if (cntr == 1) {System.out.println("Congratulations! You've guessed the number on your first attempt!");;
}
else {System.out.println("Congratulations! You've guessed the number, it took you " + cntr + " tries");}
}
}
You need to parse your input. decimalguessed is a string, and so you can't do comparisons like decimalguessed % 1.
You can convert it to an integer like this:
int guess = 0;
try {
guess = Integer.parseInt(decimalguessed);
} catch (NumberFormatException e) {
System.out.println("Your guess was not an integer: " + e.getMessage());
System.exit(1);
}
This will handle both cases where decimalguessed contains letters, and where it contains decimal points/fractions. decimalguessed is still a string, but guess now contains the integer version of it, so you can compare it to randomnumber properly. (Your loop would have never exited before, because a string is never == an integer)
Some other notes:
You should never have:
if (condition) {
return true;
} else {
return false;
}
This can always be simply replaced with
return condition;
It feels like you're very new to this. Welcome to programming!
So first, in Java generally you're not going to have all of that instantiation and variables stuff outside of your main function, unless you're going to make everything static. I would move all of that into your main function, un-static the decimalguessed variable and setup your verifyLetters function to take an argument of String decimalguessed. It may also be wise to check if the value is a number, rather than seeing if it is not a letter. There a lot of non-number, non-letter characters.
Once you've figured out that the guess is a number, you need to tell java it is one (cast it) to a decimal, then do you further comparisons against that decimal.
Darth Android also makes some good points, especially about booleans. You should never have the only result of an if/else be to return a boolean, just return the boolean. Also avoid comparisons to true/false, just do the if on the function/variable alone, or negate it with an '!' to check for false.
Good luck!
... if instead of a number I get a letter, or a symbol, or 2 decimals.
I am making a change maker program in java.
Everything works good, the only thing i am confused about is checking the string to see if is invalid for my use,
I did this for when is left empty;
if (s1.isEmpty()) {
JOptionPane.showMessageDialog(null, "Invalid input! ");
System.exit(0);
}
That works perfect, now how can I do the else to check for letters or dots or symbols, anything that is not a number?
You could use regular expressions.
Here's some sample code to check for digits only (\\d) in your input string.
The code that actually checks is pattern.matcher(in).matches() and it tries to match the regular expression defined by regex
Let me know if you need more explanations
public class HelloWorld{
public static void main(String[] args) {
String regex = "\\d+";
String inputNumber = "2";
String inputDecimal = "2.0";
String inputString = "two";
String[] inputs = {inputDecimal, inputNumber, inputString };
Pattern pattern = Pattern.compile(regex);
for(String in: inputs){
System.out.print( in + " ");
System.out.print( pattern.matcher(in).matches()? "":"does not");
System.out.print( " contain integer numbers" );
System.out.println("---");
}
}
}
If you need to perform all the processing only when the String is integer why not check for integer value in the if clause and let the else clause be common for all the letter, dots, symbols and also empty.
if(s1.isNum){
//all processing here
}
else{
JOptionPane.showMessageDialog(null,"Invalid Input");
System.out.exit(0);
}
Otherwise you could also use try and catch block.
try{
int num= Integer.parseInt(s1);
//rest of the processing
}
catch(Exception e){
JOptionPane.showMessageDialog(null,"Invalid Input");
System.out.exit(0);
}
Use either according to your requirement
You could use a regular expression1 and String.matches(String) which Tells whether or not this string matches the given regular expression. \\d+ should match one or more digits. Something like
System.out.println("12".matches("\\d+"));
Prints
true
1Some people, when confronted with a problem, think
“I know, I'll use regular expressions.” Now they have two problems. --jwz
To test whether it is an integer, parse it to an int like this:
Integer.parseInt(s1)
You might also want to make use of the value returned but I don't show it here. Now you can apply try catch blocks around the method call and catch NumberFormatException like this:
try {
Integer.parseInt(s1);
//The code here will run if s1 is an integer.
} catch (NumberFormatException e) {
//this will be executed when s1 is not an integer
}
You can also extract a method from the above code. A method that returns true when the exception is not thrown. However, a disadvantage of try catch is that throwing an exception needs time and thus, it slows down your program.
To test whether the string is a letter, you loop through all the chars in the string and use one of the methods of the Character class.
boolean isLetter = true;
for (int i = 0 ; i < s1.length() ; i++) {
if (!Character.isLetter(s1.charAt(i))) {
isLetter = false;
break;
}
}
If isLetter is true, it is a letter. Again, you can also extract this as a method.
To check whether it is a symbol, use one of the methods of the Character class (again).
boolean isSymb = true;
for (int i = 0 ; i < s1.length() ; i++) {
if (!Character.isJavaIdentifierStart(s1.charAt(i))) {
isSymb = false;
break;
}
}
To check for dots in a string, just use
s1.contains(".")
Isn't that simple?
Ok, I solved the problem the following way... I took a little bit of every idea lol...
if (s1 == null) {
JOptionPane.showMessageDialog(null, "You must enter a valid integer");
System.exit(0);
}
if (s1.isEmpty()) {
JOptionPane.showMessageDialog(null, "You must enter a valid integer");
System.exit(0);
}
for (int i = 0; i < s1.length(); i = i + 1) {
if (!Character.isDigit(s1.charAt(i))) {
JOptionPane.showMessageDialog(null, "You must enter an integer value");
System.exit(0);
}
}