Java Loop Confusion - java

I wrote this code that was intended to read a file with integer values. If the integer values are >= 0 and <=100 I need to give the average of the grades. If there are any values out of the specified range 0-100 then I need to count the incorrect integer grades, inform the user of the incorrect grades, and inform how many incorrect grades there were. I attempted the code but I keep getting the error code:
Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at Project9.main(Project9.java:26)
Code sample:
public static void main(String[] args) throws IOException{
String file;
int readInts;
Scanner k = new Scanner(System.in);
System.out.println("Enter filename: ");
file = k.nextLine();
int counterWrong = 0;
int counterRight = 0;
int sum = 0;
double average = 1.0 * sum/counterRight;
File fileReader = new File(file);
if (fileReader.exists()) {
Scanner input = new Scanner(fileReader);
while (input.hasNext()) {
readInts = input.nextInt();
System.out.println(readInts);
String a = input.next();
int a2 = Integer.parseInt(a);
if (a2 <= 100 && a2 >= 0){
counterRight++;
sum = sum + a2;
System.out.println("Score " + a2 + " was counted.");
} else {
counterWrong++;
System.out.println("The test grade " + a2 + " was not scored as it was out of the range of valid scores.");
System.out.println("There were " + counterWrong + " invalid scores that were not counted.");
}
}
if (counterRight > 0){
System.out.println("The average of the correct grades on file is " + average + ".");
}
} else {
System.out.println("The file " + file + " does not exist. The program will now close.");
}
}
}

You are doing a single check hasNext but then you read twice from scanner using nextInt() and next().

There may be two issues with your code I see.
file = k.nextLine(); // Depending on how your file is set up k.nextLine() or k.next() or maybe k.nextInt() may be useful.
while (input.hasNext()) {
readInts = input.nextInt(); // input.hasNext() assumes the next value the scanner is reading has a string value which would make readInts = input.nextInt(); impossible to use without parsing (or some other method).
I thought it'd be fun to try out this exercise (didn't want to ruin it for you). Check out my code and hopefully you'll pick up on some of the concepts I was talking about.
Note: My program reads integer values like 95 185 23 13 90 93 37 125 172 99 54 148 53 36 181 127 85 122 195 45 79 14 19 88 34 73 92 97 200 167 126 48 109 38. Which uses hasNext() & next() to get every token listed. So using nextLine() wouldn't be useful for the given input.
package cs1410;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.swing.JFileChooser;
public class Grader {
public static void main(String[] args) throws IOException {
int count = 0;
int sum = 0;
double ave = 0;
int incorrectCount = 0;
String correctGrades = "";
String incorrectGrades = "";
// Read file input
JFileChooser chooser = new JFileChooser();
if (JFileChooser.APPROVE_OPTION != chooser.showOpenDialog(null)) {
return;
}
File file = chooser.getSelectedFile();
// Scan chosen document
Scanner s = new Scanner(file);
// While the document has an Int
while (s.hasNextInt()) {
// Convert our inputs into an int
int grade = Integer.parseInt(s.next());
if (grade >= 0 && grade <= 100) {
// adds sum
sum += grade;
// increments correct count
count++;
// displays valid grades
correctGrades += Integer.toString(grade) + "\n";
} else {
// increments incorrect count
incorrectCount++;
// displays invalid grades
incorrectGrades += Integer.toString(grade) + "\n";
}
}
// Created average variable
ave = sum / count;
// bada bing bada boom
System.out.println("The number of correct grades were " + correctGrades);
System.out.println("The average score on this test was " + ave + "\n");
System.out.println("The number of incorrect grades were " + incorrectCount + "\n");
System.out.println("The incorrect values for the grades were " + "\n" + incorrectGrades);
}
}

Use hasNextInt() instead of hasNext().
hasNext() only means there is another token, not necessarily that there is another integer which you are assuming when you wrote nextInt().
Here's the documentation for hasNext() and hasNextInt()
You also want to do a check before this line:
String a = input.next();

Related

How can I get the system output value after the whole loop is done?

this is my first question in this community as you can see I'm a beginner and I have very little knowledge about java and coding in general. however, in my beginner practices, I came up with a little project challenge for myself. as you can see in the figure, the loop starts and it prints out the number that is given to it through the scanner. the problem with my attempt to this code is that it gives me the output value as soon as I press enter. what I want to do is an alternative of this code but I want the output values to be given after the whole loop is done all together.
figure
So, basically what I want is to make the program give me the input values together after the loop ends, instead of giving them separately after each number is put.
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
calc(); }
public static int calc (){
Scanner scan = new Scanner(System.in);
int count = 1;
int pass = 0;
int notpass = 0;
System.out.println("how many subjects do you have? ");
boolean check = scan.hasNextInt();
int maxless = scan.nextInt();
if (check){
while(count <= maxless ){
System.out.println("Enter grade number " + count);
int number = scan.nextInt();
System.out.println("grade number" + count + " is " + number);
if (number >= 50){
pass++;
}else{
notpass++;
}
count++;
}
System.out.println("number of passed subjects = " + pass);
System.out.println("number of failed subjects = " + notpass);
}else{
System.out.println("invalid value!");
} return pass;
}
}
I think what you want to do is create an array of int numbers.
It would be something like this:
import java.util.Scanner;
public class Application {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int maxless = 5;
int[] numbers = new int[maxless];
int count = 0, pass = 0, notPass = 0;
while(count < maxless){
System.out.println("Enter grade number " + (count + 1) + ":");
numbers[count] = scan.nextInt();
if(numbers[count] >= 50){
pass++;
}
else{
notPass++;
}
count++;
}
for(int i=0; i<maxless; i++){
System.out.println("Grade number " + (i + 1) + " is " + numbers[i]);
}
}
}
The output is the following:
Enter grade number 1:
90
Enter grade number 2:
76
Enter grade number 3:
54
Enter grade number 4:
67
Enter grade number 5:
43
Grade number 1 is 90
Grade number 2 is 76
Grade number 3 is 54
Grade number 4 is 67
Grade number 5 is 43
When dealing with arrays, just remember that the indexation begins at 0. You can read more about arrays here: http://www.dmc.fmph.uniba.sk/public_html/doc/Java/ch5.htm#:~:text=An%20array%20is%20a%20collection,types%20in%20a%20single%20array.
A tip: it's gonna be easier to help if you post the code on your question as a text, not an image, so we can copy it and try it on.
Approach 1 :
You can use ArrayList from Collection Classes and store the result there and after the loop is completed, just print the array in a loop.
Example :
//Import class
import java.util.ArrayList;
//Instantiate object
ArrayList<String> output = new ArayList();
while(condition){
output.add("Your data");
}
for(i = 0; i < condition; i++){
System.out.println(output.get(i));
}
Approach 2 :
Use StringBuilder class and append the output to the string, after the loop is completed, print the string from stringbuilder object.
Example :
//import classes
import java.util.*;
//instantiate object
StringBuilder string = new StringBuilder();
while(condition){
string.append("Your string/n");
}
System.out.print(string.toString());
Approach 3 : (As mentioned by Sarah)
Use arrays to store the result percentage or whatever and format it later in a loop. (Not a feasible approach if you want to store multiple values for the same student)
Example :
int studentMarks[] = new int[array_size];
int i = 0;
while(condition){
studentMarks[i++] = marks;
}
for(int j = 0; j < i; j++)
System.out.println("Marks : " + studentMarks[j]);

Reading from File - Error "Exception in thread "main" java.util.NoSuchElementException: No line found"

I am writing a program that reads from a file titled "grades.txt" and displays the student's name, three grades, and the average of those three grades.
The text file looks like this:
Bobby
Doe
65
65
65
Billy
Doe
100
100
95
James
Doe
85
80
90
Here is the code. I am able to read from the file and output everything correctly.
import java.util.Scanner; // Needed for Scanner class.
import java.io.*; // Needed for I/O class.
public class TestScoresRead
{
public static void main(String[] args) throws IOException
{
// Open the file
File file = new File("Grades.txt");
Scanner inputFile = new Scanner(file);
// Read lines from the file
while (inputFile.hasNext())
{
String firstName = inputFile.next();
String lastName = inputFile.next();
double grade1 = inputFile.nextDouble();
double grade2 = inputFile.nextDouble();
double grade3 = inputFile.nextDouble();
String nextLine = inputFile.nextLine();
int total = (int)grade1 + (int)grade2 + (int)grade3;
int average = total / 3;
System.out.println("Name: \t" + firstName + " " + lastName);
System.out.println("Test 1:\t" + grade1);
System.out.println("Test 2: \t" + grade2);
System.out.println("Test 3: \t" + grade3);
System.out.println("");
System.out.println("Average: " + average);
if (average < 60)
System.out.println("Grade : \t F");
else if (average < 70)
System.out.println("Grade : \t D");
else if (average < 80)
System.out.println("Grade: \t C");
else if (average <90)
System.out.println("Grade: \t B");
else
System.out.println("Grade: \t A");
System.out.println("");
}
inputFile.close();
}
}
However, I keep getting this error and I am not sure why:
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at TestScoresRead.main(TestScoresRead.java:21)
From the research I've done, I believe it has something to do with going from nextLine to nextDouble, and the \n being stuck in the keyboard buffer.
Or maybe I'm not using hasNext right?
How can I fix the error?
remove this line
String nextLine = inputFile.nextLine();

Having some trouble with File I/O

I have a homework assignment to read data from a file which contains names and scores per game of basketball players. The program is supposed to output the names and scores of the players, as well as tally each player's average score per game, and finally display the player with the highest average. I am currently stuck on trying to get the average and a newline character for each player.
Here is a pic of the input file I am reading the data from.
and here is my code:
import java.util.Scanner;
import java.io.File;
import java.io.PrintWriter;
import java.io.IOException;
public class BasketballTeam
{
public static void main(String[] args) throws IOException
{
File f = new File("BasketballData.txt");
if (f.exists())
{
Scanner input = new Scanner(f);
int games = 0;
int totalScore = 0;
double avg = 0.0;
while (input.hasNext())
{
String s = input.next();
System.out.printf("%-9s", s);
int a = input.nextInt();
while (input.hasNextInt())
{
if (a == -1)
{
avg = (double)totalScore/games;
System.out.printf("%14s%.2f\n", "Average of ", avg);
games = 0;
totalScore = 0;
s = input.next();
}
else
{
System.out.printf("%5s", a);
games++;
totalScore = totalScore + a;
a = input.nextInt();
}
}
}
}
}
}
When I run the program, my output is just a single line that looks like:
Smith 13 19 8 12Badgley 5Burch 15 18 16Watson......and so on
Why am I not getting any newline characters or my average? I want my output to look like this:
Smith 13 19 8 12 Average of 13
Badgley 5 Average of 5
Burch 15 18 16 Average of 16.33
.....and so on
Thanks in advanced for any suggestions/corrections.
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class BasketballTeam
{
public static void main(String[] args) throws IOException
{
File f = new File("BasketballData.txt");
if (f.exists())
{
Scanner input = new Scanner(f);
int games = 0;
int totalScore = 0;
double avg = 0.0;
while (input.hasNext())
{
String s = input.next();
System.out.printf("%-9s", s);
while (input.hasNextInt())
{
int a = input.nextInt();
if(a != -1)
{
System.out.printf("%5s", a);
games++;
totalScore = totalScore + a;
}
}
avg = (double)totalScore/games;
System.out.printf("%14s%.2f\n", "Average of ", avg);
games = 0;
totalScore = 0;
System.out.println();
}
input.close();
}
}
}
This is what you are looking for. You don't even need the -1 at the end of each line in the file you can get rid of that if you want unless it is part of the specification. It will work without the -1. Your inner loop you just want to add up your totals then outside of the inner loop get your average and display. Then reset your variables. You were pretty close just needed to change a couple things. If you have any questions on how this works just ask away. Hope this helps!
Try
avg = ((double)totalScore/(double)games);
and replace \n with \r\n:
System.out.printf("%14s%.2f\r\n", "Average of ", avg);
I would highly recommend using a FileReader:
File file = new File("/filePath");
FileReader fr = new FileReader(file);
Scanner scanner = new Scanner(fr);
//and so on...
In this line a = input.nextInt(), you already advance to the next int, so the test input.hasNextInt() will be false when you reach -1.
One possible solution is to change the loop to:
while (input.hasNext()) {
String s = input.next();
System.out.printf("%-9s", s);
int a = 0;
while (input.hasNextInt()) {
a = input.nextInt();
if (a == -1) {
avg = (double) totalScore / games;
System.out.printf("%14s%.2f\n", "Average of ", avg);
games = 0;
totalScore = 0;
} else {
System.out.printf("%5s", a);
games++;
totalScore = totalScore + a;
}
}
}

Logic Error in Java Program

Writing a program that reads in numbers from a text file and tests them to see if they are prime or not. Text file consists of the following numbers: 98, 76, 84, 69, 92, 83, 88, 90, 72, 66. The first number, 98 is not prime, but then the second number (76) should come out as Prime. My printed out results show all the numbers being Not Prime which is not true.
import java.io.*;
import java.util.Scanner;
public class AssignFive_FileRead {
public static void main(String[] args) throws IOException {
int number;
int calc = 0;
int i = 2;
File myFile = new File("Numbers.txt");
Scanner inputFile = new Scanner(myFile);
// Check to see if file exists
if (!myFile.exists()) {
System.out.println("Error: file cannot be found");
System.exit(0);
} else {
System.out.println("File has been found, starting operation...");
}
// Reading numbers from text file
while (inputFile.hasNext()) {
number = inputFile.nextInt();
// Begin calculation to see if number is prime
while (i <= number / 2) {
if (number % i == 0) {
calc = 1;
}
i++;
} // End second while loop
if (calc == 1) {
System.out.println("Number: " + number + " is Not Prime!");
} else {
System.out.println("Number: " + number + " is Prime!");
}
} // End first while loop
} // End main
} // End public class
There is a bug in your code (I just spotted it).
But the big error is in your testing methodology.
You say that 76 is a prime number. It isn't. 76 is 38 x 2, and that means it is not prime. (Indeed, any positive number that is even and larger than 2 is not prime ...)
In fact, 83 is the only prime number in that list.
Init calc whenever you read a number
// Reading numbers from text file
while (inputFile.hasNext()) {
number = inputFile.nextInt();
// Begin calculation to see if number is prime
calc = 0;
while (i <= number / 2) {
// [...]
You should reset both i and calc every time you come out from second while loop. I have fixed it by using the following code
import java.io.*;
import java.util.Scanner;
public class AssignFive_FileRead {
public static void main(String[] args) throws IOException {
int number;
int calc = 0;
int i = 2;
File myFile = new File("input.txt");
Scanner inputFile = new Scanner(myFile);
// Check to see if file exists
if (!myFile.exists()) {
System.out.println("Error: file cannot be found");
System.exit(0);
} else {
System.out.println("File has been found, starting operation...");
}
// Reading numbers from text file
while (inputFile.hasNext()) {
number = inputFile.nextInt();
// Begin calculation to see if number is prime
while (i <= number / 2) {
if (number % i == 0) {
calc = 1;
}
i++;
} // End second while loop
if (calc == 1) {
System.out.println("Number: " + number + " is Not Prime!");
} else {
System.out.println("Number: " + number + " is Prime!");
}
calc = 0;
i=2;
} // End first while loop
} // End main
} // End public class

Printing out student averages with file input using string tokenizer and scanner

I am trying to get the averages of values in a text file. The content of the file is:
Agnes 56 82 95 100 68 52
Bufford 87 92 97 100 96 85 93 77 98 86
Julie 99 100 100 89 96 100 92 99 68
Alice 40 36 85 16 0 22 72
Bobby 100 98 92 86 88
I have to skip the names, and try to sum the values of the integers of each line. The ouput should be something like this:
Agnes, average = 76
Bufford, average = 91
Julie, average = 94
Alice, average = 39
Bobby, average = 93
My problem is that i am unable to sum the values (using sum+=sc1.nextInt()). I also cant count the number of tokens of just the integers. For example, for the first line I need countTokens to equal 6, but i get 7, even after I skip the name.
import java.io.*;
import java.util.*;
public class studentAverages
{
public static void main() throws IOException
{
Scanner sf = new Scanner(new File("C:\\temp_Name\\StudentScores.in"));
int maxIndex = -1;
String text[] = new String[100];
while(sf.hasNext( ))
{
maxIndex++;
text[maxIndex] = sf.nextLine();
}
sf.close();
int sum=0;
int avg=0;
int divisor=0;
for (int i=0;i<=maxIndex; i++)
{
StringTokenizer sc= new StringTokenizer(text[i]);
Scanner sc1= new Scanner (text[i]);
while (sc1.hasNext())
{
sc1.useDelimiter(" ");
sc1.skip("\\D*");
System.out.print(sc1.nextInt());
System.out.println(sc1.nextLine());
sum+=sc1.nextInt(); // trying to sum all the numbers in each line, tried putting this line everywhere
avg=sum/divisor;
break;
}
System.out.println(avg);
while (sc.hasMoreTokens())
{
divisor=sc.countTokens()-1; //Not able to count tokens of just the numbers, thats why I am using -1
//System.out.println(divisor);
break;
}
}
//this is for the output
/*for (int i=0; i<=maxIndex; i++)
{
String theNames="";
Scanner sc= new Scanner (text[i]);
theNames=sc.findInLine("\\w*");
System.out.println(theNames + ", average = ");
}*/
}
}
I would recommend splitting each line using the split method and then looping through those values while ignoring the first, because you know that is the title.
public static void main() throws IOException {
Scanner sf = new Scanner(new File("C:\\temp_Name\\StudentScores.in"));
int maxIndex = -1;
String text[] = new String[100];
while(sf.hasNext( )) {
maxIndex++;
text[maxIndex] = sf.nextLine();
}
sf.close();
for(int i = 0; i < maxIndex; i ++) {
String[] values = text[i].split(" ");
String title = values[0];
int sum = 0;
for(int j = 1; i < values.length; j ++) {
sum += Integer.parseInt(values[j]);
}
double average = sum / (values.length - 1);
System.out.println(title + ": " + average);
}
}
Notice that the inner loop's index begins at 1 and not 0, and that when calculating the average, we subtract one from the size of the values array because we want to ignore the title.
Try this one:
Scanner scanner = new Scanner(new File("resources/abc.txt"));
//check for next line
while (scanner.hasNextLine()) {
//create new scanner for each line to read string and integers
Scanner scanner1 = new Scanner(scanner.nextLine());
//read name
String name = scanner1.next();
double total = 0;
int count = 0;
//read all the integers
while (scanner1.hasNextInt()) {
total += scanner1.nextInt();
count++;
}
System.out.println(name + ", average = " + (total / count));
}
scanner.close();
output:
Agnes, average = 75.5
Bufford, average = 91.1
Julie, average = 93.66666666666667
Alice, average = 38.714285714285715
Bobby, average = 92.8
--EDIT--
Here is the code as per your last comment (I have to use StringTokenizer`/string methods like useDelimiter, skip, etc to arrive at the answer)
Scanner sf = new Scanner(new File("resources/abc.txt"));
List<String> text = new ArrayList<String>();
while (sf.hasNext()) {
text.add(sf.nextLine());
}
sf.close();
for (String str : text) {
StringTokenizer sc = new StringTokenizer(str, " ");
double sum = 0;
int count = 0;
String name = sc.nextToken();
while (sc.hasMoreElements()) {
sum += Integer.valueOf(sc.nextToken());
count++;
}
System.out.println(name + ", average = " + (sum / count));
}
}
output
Agnes, average = 75.5
Bufford, average = 91.1
Julie, average = 93.66666666666667
Alice, average = 38.714285714285715
Bobby, average = 92.8

Categories

Resources