Exceptions and File I/O - java

Hello people I need help, when I run my code it outputs this :
Average = 49.91791791791792
null
empty.txt is empty
Error: notThere.txt (No such file or directory)
Average = 0.0
but my goal is to have it output this:
Average = 49.91791791791792
squeeze.txt does not have numeric data
empty.txt is empty
Error: notThere.txt (No such file or directory)
Average = 0.0
I have problems understanding this step for the assignment:
Throw the following exceptions in the scanDataAndCalculateAverage method
File is empty.
File has non-numeric data. You can assume that the data file does not have non-numeric and numeric data mixed in. This is done by checking if something was read in but the count is 0.
Can you guys help me? Here is the code:http://pastebin.com/33WCBxEf
public class Average {
long total = 0;
int count = 0;
String asd = "";
public Average(String a){
asd = a;}
public double scanDataAndCalculateAverage(){
try {
FileReader f = new FileReader(asd);
Scanner in = new Scanner(f);
while (in.hasNext()){
total += in.nextInt();
count++;
}
if(count==0 && in.hasNext() == true){
throw new IllegalArgumentException(asd + " does not have numeric data");
}
if(count == 0 && total == 0){
throw new ArithmeticException(asd + " is empty");
}
return (double)total/count;
} catch (IOException e){
System.out.println("Error: " + e.getMessage());
return 0;
}
}
}

The problem is in the while loop:
while (in.hasNext()){
total += in.nextInt();
count++;
}
This loop exits only when hasNext returns false, which meanse count==0 && in.hasNext will never be true. Probably, you want the loop to only process ints.
This might work better:
while (in.hasNextInt()){
total += in.nextInt();
count++;
}
The loop will end when there is no int - however hasNext will still be true, since there may be letters, etc in the file.

while (in.hasNextInt()){
total += in.nextInt();
count++;
}
if(count==0 && in.hasNextInt() == false){
throw new IllegalArgumentException(asd + " does not have numeric data");
}
Yeah thats most probably it. Try it!

Related

having some trouble with a while loop, and getting an if statement to execute

This is an exercise we are doing in our last chapter of the book. I covered everything except the if statement that requires the input to follow a number after a comma.
For example: John Doe, nine
output should trigger, comma should follow integer. I am trying to get the if statement to at least recognize that if the input after the comma is not a number then the output if statement should trigger but I can't.
What is working at least is input statements with more than one comma.
The expected format should be:
Jane Doe, 9
while (!datapoint.equals("-1")) {
System.out.println("Enter a data point (-1 to stop input):");
datapoint = scnr.nextLine();
int commaCount = 0;
for( int i= 0; i < datapoint.length(); i++)
{
if(datapoint.charAt(i) == ',')
commaCount++;
}
if (commaCount > 1) {
System.out.println("Error: Too many commas in input.");
}
if (datapoint.equals("-1")) {
break;
}
if (!datapoint.contains(",")) {
System.out.println("Error: No comma in string.");
}
if (datapoint.contains(",")) {
String[] values = datapoint.split(",");
temp1 = values[0];
temp2 = values[1];
temp1 = temp1.replace(",", ""); // commma removed ex/ Jane Austen
temp2 = temp2.replace(" ", ""); // space removed ex/ 6
String trigger = temp2;
if (values.length == 2) {
if (temp2.length() > 2) { //if datapoint does not contain a number after commma
System.out.println("Error: Comma not followed by an integer.");
}
if (trigger.length() < 3) {
int convert = Integer.parseInt(temp2); // converts string to integer
System.out.println("Data string: " + temp1);
System.out.println("Data integer: " + convert); // 2
names.add(temp1);
ints.add(convert);
}
}
}
System.out.println();
}
Stop, back up and take a deep breath ... I seem to be saying that a lot lately.
Break the problem down and then, step by step, try and solve each problem, not try and do the whole thing, because your confused and I'm confused.
If we assume Jane Doe, 9 is a valid format, then we can start from there.
We can simply split the String on the comma doing something like...
String[] parts = value.split(",");
Based on the "valid" input, we would end up with ["Jane Doe", " 9"], sweet. So we can do a basic validation using something like...
if (parts.length == 2) {
} else {
System.out.println("Invalid input, expecting [String],[int]");
}
Okay, sweet. Now we can valid the individual parts of the String
First, we should check to see if the name isn't blank. Then we should try and determine if the second part is an integer or not. Not, here's a neat trick I think people miss out on - you can use more then one Scanner and use it validate the String 😱
if (parts[0].isBlank()) {
System.out.println("Name can not be blank");
} else {
Scanner parser = new Scanner(parts[1].trim());
if (parser.hasNextInt()) {
int intValue = parser.nextInt();
} else {
System.out.println("[" + parts[1] + "] is not a valid integer");
}
}
Now, we can do some quick validation...
String value = "Jane Doe, 9";
String[] parts = value.split(",");
if (parts.length == 2) {
if (parts[0].isBlank()) {
System.out.println("Name can not be blank");
} else {
Scanner parser = new Scanner(parts[1].trim());
if (parser.hasNextInt()) {
int intValue = parser.nextInt();
System.out.println(parts[0] + " = " + intValue);
} else {
System.out.println("[" + parts[1] + "] is not a valid integer");
}
}
} else {
System.out.println("Invalid input, expecting [String],[int]");
}
Just change the value variable and double check your...my logic, quick simple and clean.
Once you have that, then you can start worrying about including the loop and getting input from other sources...
Honestly, I think the do-while is underrated. Think about it, you MUST do a least one interaction of the loop, so why check the exit condition at the start!?
boolean stop = false;
do {
System.out.println("Enter a data point (-1 to stop input):");
String value = scnr.nextLine();
// Handle the exit condition first, get it out of the way
if ("-1".equals(value)) {
stop = true;
} else {
String[] parts = value.split(",");
if (parts.length == 2) {
if (parts[0].isBlank()) {
System.out.println("Name can not be blank");
} else {
Scanner parser = new Scanner(parts[1].trim());
if (parser.hasNextInt()) {
int intValue = parser.nextInt();
System.out.println(parts[0] + " = " + intValue);
} else {
System.out.println("[" + parts[1] + "] is not a valid integer");
}
}
} else {
System.out.println("Invalid input, expecting [String],[int]");
}
}
} while (!stop);

Exception in thread ... : null - trying to convert String from file to Integer

like in the title , I'm stuck with this error for a while .I get the value from the file normally but when I try to convert it the error poops out. I read many topics ,but couldn't find any similar case to mine(with file) or any good tips. I tried adding an assert ,but it didn't help. The full description of error is :
Exception in thread "main" java.lang.NumberFormatException: null
at java.base/java.lang.Integer.parseInt(Integer.java:620)
at java.base/java.lang.Integer.parseInt(Integer.java:776)
at EnergyMeasure_needs_to_be_completed.main(EnergyMeasure_needs_to_be_completed.java:85)
Also I'm beginner (but I guess you already know that heh ;))
import java.util.Scanner;
import java.io.*;
public class EnergyMeasure_needs_to_be_completed {
public static void main(String[] args) throws IOException {
//int work_of_energy;
Scanner input = new Scanner(System.in);
System.out.println("\t\t\t\t Hi , this program will count how many kWh you're using");
//asks about number of devices
System.out.println("First of all, how many the same devices do you have in your house ?");
int devices = input.nextInt();
boolean bool = false;
do {
if (devices < 0) {
System.out.println("You can't have less than 0 devices in your home!\nMake input once again :");
devices = input.nextInt();
} else {
System.out.println("Okay, so you've got " + devices + " same devices.");
bool = true;
break;
}
}while(bool = true);
//asks about time of use
System.out.println("\nHow many hours you use them per day?");
int time_use = input.nextInt();
do {
if (time_use > 24 || time_use < 0) {
System.out.println("Wrong!\nMake input once again :");
time_use = input.nextInt();
}
else{
System.out.println("You use your devices for " + time_use + "h");
bool = true;
break;
}
}while(bool = true);
/*else if(!input.hasNextInt()){
System.out.println("Invalid input! \nEnter an integer : ");
time_use = input.nextInt();
} */
//downloads value of power from file
String power_dev; //path to the file
power_dev = null; //reference to one line at a time
try {
FileReader fileReader = //reads text files in the default encoding
new FileReader("power_monitors");
BufferedReader bufferedReader = //deal with a line at a time
new BufferedReader(fileReader);
while((power_dev = bufferedReader.readLine()) != null) {
System.out.println("\nThe power of your devices is " + power_dev + "W");
}
bufferedReader.close(); //close file
}
catch (FileNotFoundException e) { //if file doesn't exist catch the except
System.out.println("Unable to open file");
}
//assert power_dev != null;
int power_dec = Integer.parseInt(power_dev); //change the String ,to Integer
int power_of_devices = power_dec * devices; //summary devices power
//count the cost of work (W = P * t) [kWh]
int work_of_energy = (power_of_devices / 1000) * time_use;
System.out.println("The work of energy equals : " + work_of_energy);
}
}
If you print power_dev, what do you get? What format is it? Because the readLine() returns a textual line, so depending on the source you are reading from, you might get more than an int.
Why not use the read() method? It returns an int, so you wouldn't have to parse power_dev.
Again, hard to answer your question without seeing the file or having a reproductible code, but my best guess is that power_dev returns null or something that can't be parsed by Integer.parseInt() method.

Error Handling (Java)

Fairly easy question, but I was basically given code to debug and I've fixed all errors but one. When trying to make the program more friendly and include error handling, I found that the error message is thrown even if the condition is satisfied (that is, the number in the array that a user searches for actually exists within the array). Not looking for a direct answer, just a hint. I've tried using combinations of if/else as well as moving around curly braces.
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer to find: ");
try {
int number = input.nextInt();
int index = Arrays.binarySearch(array, number);
for (int i = 0; i < array.length; i++) {
if ( array[i] == number )
System.out.println("Found " + number + " at index " + index++);
}
System.out.printf("Your number was not found within the array.");
}
catch (InputMismatchException e){
System.out.printf("Sorry, but it looks like you entered something other than an integer. Please try again.");
}
}
Console output example:
Enter an integer to find: -9
Found -9 at index 0
Your number was not found within the array.
Array.binarySearch will return the index if it finds the value, otherwise it will return -1.
If index == -1, you can print the "not found message" without entering the loop at all.
Otherwise, if index > 0, then you can enter the loop and iterate over the array to find each index where the value is a match.
This is required if you want a message for multiple matches as binarySearch will just return the the first index the value was found at.
As an aside, binarySearch requires the array to be sorted first, otherwise the results will be undefined. I don't know if this is a problem as array is declared outside of the example.
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer to find: ");
try {
int number = input.nextInt();
int index = Arrays.binarySearch(array, number);
if (index > 0) {
for (int i = 0; i < array.length; i++) {
if ( array[i] == number ) {
System.out.println("Found " + number + " at index " + i);
}
}
} else {
System.out.printf("Sorry, your number wasn't found.");
}
}
catch (InputMismatchException e) {
System.out.printf("Sorry, but it looks like you entered something other than an integer. Please try again.");
}
in your code:
"Your number was not found within the array." will always be printed unless there is an exception caught by catch block
also one interesting thing about binary search is :
if an element is not present in the array, it returns negative of the probable position if the searched element "would have been" present.
Example : in this program, if you search for 9,it will return -3
if you search for 65,it will return -6
This will work correctly:
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Scanner;
public class debug {
public static void main(String...args){
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer to find: ");
int i, array[]={-9,8,14,56,64};
try {
int number = input.nextInt();
int index = Arrays.binarySearch(array, number);
if(index>=0)
System.out.println("Found " + number + " using binary search at index " + index);
else
System.out.println("Not Found !! index returned by binary search is : "+index);
boolean flag=false;
for (i = 0; i < array.length; i++) {
if ( array[i] == number ){
flag=true;
break;
}
}
if(flag)
System.out.println("Found " + number + " using for loop at index " + i);
else
System.out.printf("Your number was not found within the array.");
}
catch (InputMismatchException e){
System.out.printf("Sorry, but it looks like you entered something other than an integer. Please try again.");
}
}
}
The condition inside the loop is wrong. If the first element of the array isn't the value you were looking for, it immediately terminates. The error handling must be after the loop. Try this:
boolean found = false;
for (int i = 0; i < array.length; i++) {
if ( array[i] == number ){
System.out.println("Found " + number + " at index " + index++);
found = true;}
}
if(!found)
throw new IllegalArgumentException("Your number was not found within the array.");

java exception handling - divide by zero and divide by text method

I've been doing java for 4 months, so I'm still an amateur. Just trying to get some hwk done. Can't seem to find the right tips for getting my denominator to function well by rejecting text data and zero while keeping in a loop with error messages. Another issue is the fact my quotient is 0.0 no matter what my numerator / denominator is. Lots of problems, any advice is appreciated. Directions are as follows:
--This program takes user input for a (int) numerator and
(int) denominator then computes and displays the (double) quotient.
--If the user enters text instead of number for the numerator, display an error message explaining the issue and keep user in a loop until the correct data is entered.
--If the user enters text or a zero instead of a number for the denominator, display an error message explaining the issue and keep user in a loop until the correct data is entered.
--Messages should be descriptive with respect to the issue.
public static void main(String[] args) throws Exception {
Scanner console = new Scanner(System.in);
int n1 = 0; //number 1
int n2 = 1; //number 2..
double r = (double) n1 / n2; //quotient
String n1Str = "Please enter a real number for the numerator";
String n2Str = "Please enter a real number greater than zero for the denominator";
String errMsg = "Please enter a real number.";
String notZero = "Denominator cannot equal zero."; // not all string msgs are used, just there in case i need them.
try {
n1 = getInteger(n1Str); // validates against alphabet
if (hasNextInt()) { // working
n1 = console.nextInt();
}
} catch (InputMismatchException ime) {
}
try {
n2 = getInteger2(n2Str); // trying to validate against alphabet & zero
if (hasNextInt()) { // not working though...
n2 = console.nextInt();
}
} catch (InputMismatchException ime) {
}
System.out.println("Fraction result is " + r);
}
public static int getInteger(String message) {
Scanner console = new Scanner(System.in);
int count = 0;
boolean isValidInteger = false;
do {
System.out.println(message);
if (console.hasNextInt()) {
isValidInteger = true;
count = console.nextInt();
} else {
console.nextLine();
}
} while (!isValidInteger);
return count;
}
public static int getInteger2(String message) {
Scanner console = new Scanner(System.in);
int count = 0;
boolean isValidInteger = false;
do {
System.out.println(message);
if (console.nextInt() != 0 || console.hasNextInt()) { // validates against zero but
isValidInteger = true; // can't get it to validate against text.
count = console.nextInt(); //tried switching statements and using && but get thrown into endless loop
}
} while (!isValidInteger);
return count;
}
private static boolean hasNextInt() {
return false;
}
}
You have lots of issues with your code.
For starters, you should have only one Scanner, that would exist throughout the lifespan of your application. There's no need to instantiate multiple scanners.
public class SomeClass {
private static Scanner console;
public static void main(String[] args) throws Exception {
console = new Scanner(System.in);
(...)
console.close();
}
}
Now lets look into your problematic getInteger2 method.
You should simple validate, as you do on your getIntegermethod, if the input is an integer. If it is, you process it; otherwise, you skip it using next() (not nextLine()) since you want to jump over the next complete token from this scanner.
public static int getInteger2(String message) {
int count = -1;
boolean isValidInteger = false;
do {
System.out.println(message);
if (console.hasNextInt()) {
count = console.nextInt();
if (count != 0) {
isValidInteger = true;
} else {
System.out.println("Denominator cannot equal zero.");
}
} else {
console.next();
}
} while (!isValidInteger);
return count;
}
Finally, your quotient is always being printed 0.0 since you're not updating its value before outputting it:
r = (double) n1 / n2;
System.out.println("Fraction result is " + r);
The fact that your quotient "r" is always 0.0 is because you initialize n1 to be 0 and n2=1; You should just declare the variables and initialize them down in your code; i.e when you want to get the values from the user.
It seems that you have two "main" problems in your code/logic...
Problem 1) You are not calculating r (your quotient) after you get the inputs.
So the lines:
} catch (InputMismatchException ime) {
}
System.out.println("Fraction result is " + r);
could be changed to something like:
} catch (InputMismatchException ime) {
}
r = (double) n1 / n2; //calculate the quotient
System.out.println("Fraction result is " + r);
Problem 2)
Your code:
do {
System.out.println(message);
if (console.nextInt() != 0 || console.hasNextInt()) { // validates against zero but
isValidInteger = true; // can't get it to validate against text.
count = console.nextInt(); //tried switching statements and using && but get thrown into endless loop
}
} while (!isValidInteger);
return count;
could be changed to something like this, if you don't want to change too much in your code:
do {
System.out.println(message);
try {
if ((count = console.nextInt()) != 0) {
isValidInteger = true;
}
} catch (InputMismatchException ime) {
return getInteger2(message);
}
} while (!isValidInteger);
return count;
so that only if the input in console is an int you read it with nextInt() and store it in count. In your code you would read the int with nextInt() and if it is an int you read it again with nextInt(), which causes the user to write in 2 ints as well as your issue that you read the int before checking that it is an int which causes the InputMismatchException to be thrown. In the code I sent you, if the read number is an int AND not 0 then it is returned, if it is 0 your loop runs again and if it isn't an int at all the the method is simply called again (see Recursion).
I hope this helps you understand the issues.
The best way, however, would probbaly be do redesign your code a bit.

Checking if String entered is a binary numer, getting incorrect output

I am trying to write a program that will check if the user-entered string is a binary number, and if it is, it will output the number of 1s in the number. I had this working fine with an integer value, but since an int can't hold more than 2 billion or whatever the max value is, I am trying to rewrite it to work with Strings.
As of right now, any number I enter will output "Number entered is not binary." and when I enter 0, I will get a StringIndexOutofBoundsException. I am a fairly novice programmer, so forgive any obvious errors I may have missed, I am just asking for a possible solution to my problem or a push in the right direction. Here is my code (after trying to make it work with Strings rather than integers):
import java.util.*;
public class BinaryHW {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
System.out.println("Enter a binary number: ");
String bin = kb.nextLine();
//the method I used to check whether or not user entered a binary
//number requires changing the value of 'bin'.
//Therefore, 'origBin' set equal to 'bin' for later use.
String origBin = bin;
int count = 0;
boolean isBinary = true;
/* if bin = 0, then this loop will be skipped because
* 0 is a binary number and need not be checked.
*/
while (Integer.parseInt(bin) != 0) {
int lastDigit = bin.charAt(bin.length() - 1);
if (lastDigit > 1) {
System.out.println("Number entered is not binary.");
isBinary = false;
break;
} else {
bin = bin.substring(bin.length() - 2);
}
}
//Again, the method I used to count the 1s in the bin number
//requires changing the value of origBin, so origBin2 is introduced
String origBin2 = origBin;
for (int i = 0; i < origBin.length(); i++) {
if (origBin.charAt(origBin.length() - 1) == 1) {
count ++;
origBin2 = origBin.substring(origBin2.length() - 2);
} else {
origBin2 = origBin.substring(origBin2.length() - 2);
}
}
if (isBinary)
if (count == 1)
System.out.println("There is "
+ count + " 1 in the binary number entered.");
else
System.out.println("There are "
+ count + " 1s in the binary number entered.");
}
}
I think you are overcomplicating things... simply iterate through your binary string, and keep track of the number of 1's reached. If a number other than 0 or 1 is found, report that input is a non-binary number. Below is a snippet which accomplishes this:
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
System.out.println("Enter a binary number: ");
String bin = kb.nextLine();
int oneCount = 0;
boolean validBinaryNum = true;
for (int i = 0; i < bin.length() && validBinaryNum; i++) {
char currentChar = bin.charAt(i);
if (currentChar == '1') oneCount++;
else if (currentChar != '0') {
validBinaryNum = false;
}
}
if (validBinaryNum && bin.length() != 0) {
System.out.println("Number of 1's: " + oneCount);
} else {
System.out.println("Number is not binary");
}
}

Categories

Resources