java.util.InputMismatchException error when scanning from a .txt file - java

I am creating a program where 2 classes are used. In one class, i create methods that are then called by the second class. All methods are contained in the first class and the 2nd class simply calls them and executes the code.
Class 1
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Student {
private Scanner scanner;
private String firstName;
private String lastName;
private int homeworkScore;
private int testScore;
private String letterGrade;
private int numberOfStudents;
public Student () {
String firstName = null;
String lastName = null;
int homeworkScore = 0;
int testScore = 0;
String letterGrade = null;
int numberOfStudents = 0;
}
public void openFile(){
try {
scanner = new Scanner(new File("grades.txt"));
} catch (FileNotFoundException e) {
System.out.println("Error opening file. Please make sure that you have a grades.txt file in the same folder as GradeCalculator.class");
System.exit(0);
}
}
public void setNumberOfStudents() {
System.out.println("It kinda works");
numberOfStudents = scanner.nextInt();
}
public void setFastName() {
fastName = scanner.next();
}
public void setLastName() {
lastName = scanner.next();
}
public void setHomeworkScore() {
int subAssignment = 0;
int assignment = 0;
for(int i = 1; i <= 21; i++) {
subAssignment = scanner.nextInt();
assignment += subAssignment;
}
homeworkScore = assignment;
}
Class 2
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class CourseGrade {
public static void main(String[] args) {
Student myStudent = new Student();
myStudent.openFile();
myStudent.setNumberOfStudents();
myStudent.setFirstName();
myStudent.setLastName();
myStudent.setHomeworkScore();
}
}
This is the error I get:
It kinda works
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at Student.setHomeworkScore(Student.java:54)
at CourseGrade.main(CourseGrade.java:20)
...the "It kinda works" statement is just to see if it was calling the method correctly, which it looks like it is.
To my understanding, the error is telling me that it is reading the wrong type from the .txt file, but idk why that would be. Is it even reading the file correctly? Any type of help would be great, as I have been staring and messing with this code for hours!

Based on the error message, and where the error occurs, most likely you are trying to read an integer, but the actual data that you are reading is not a number.
You could verify this by changing your scanner.nextInt() to a scanner.next() and printing out the value that you actually get. Alternatively, you could add “error handling” of the form:
for(int i = 1; i <= 21; i++) {
if (scanner.hasNextInt()
subAssignment = scanner.nextInt();
else
throw new RuntimeException("Unexpected token, wanted a number, but got: " + scanner.next());
assignment += subAssignment;
}

According to the oracle java documentation, that exception is thrown, when the token doesn't fit the requested pattern (int) or is out of range.
If there's no more int in your file, that exception is thrown.
You could avoid that exception by checking if there's another int value to read with Scanners method hasNextInt.
For example:
for(int i = 1; i <= 21 && scanner.hasNextInt(); i++) {
subAssignment = scanner.nextInt();
assignment += subAssignment;
}
(if that doesn't solve your problem, you should also include your input file)

Related

Can't understand how to solve noSuchElementException?

I'm trying to write a program to read a file called scores.txt where it prints out the ID of the student with the highest average across their courses along with their student ID.
This is what scores.txt looks like:
34 c081 c082 c083 c084
S2023 99 75 85 62
S2025 -1 92 67 52
S1909 100 83 45 -1
So basically, the 34 a the beginning is a 3 for the number of students and a 4 for the number of courses (yes, I know this is silly, but the file was provided for my task). The c numbers such as c081 are course codes at the school, and the s numbers such as s2023 are student numbers. The figures in the middle represent their scores, the -1 also means they weren't enrolled in the unit.
Anyway, so far I've written a MySchool class and a Student class, which I'll paste below:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class MySchool {
public static void main(String[] args) {
int numberOfStudents;
ArrayList<Student> allStudents = new ArrayList<Student>() ;
// grab first line only, and check if first target is integer, or string
try {
File scoresFile = new File("Scores.txt");
Scanner scoresFileReader = new Scanner(scoresFile);
String headerRow = scoresFileReader.nextLine();
numberOfStudents = headerRow.charAt(0);
while(scoresFileReader.hasNextLine()) {
for (int studentI = 0; studentI < numberOfStudents; studentI++) {
String studentText = scoresFileReader.nextLine();
System.out.println(studentText);
Student student = new Student(studentText);
allStudents.add(student);
}}
scoresFileReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred");
e.printStackTrace();
}
float highestAverage = 0;
String highestScoringStudentNumber = null;
for (Student student : allStudents) {
if (student.getAverageScore() > highestAverage) {
highestAverage = student.getAverageScore();
highestScoringStudentNumber = student.getStudentNumber();
}
}
System.out.println("Highest scoring student: " + highestScoringStudentNumber);
}
}
import java.util.ArrayList;
public class Student {
private String studentNumber;
private ArrayList<Integer> scores = new ArrayList<Integer>();
public Student(String studentText) {
String[] parts = studentText.split(studentText, ' ');
this.studentNumber = parts[0];
for (int i = 1; i < parts.length - 1; i++) {
scores.add(Integer.parseInt(parts[i + 1]));
}
}
public String getStudentNumber() {
return this.studentNumber;
}
public float getAverageScore() {
int sum = 0;
for (int i = 0; i <this.scores.size(); i++) {
sum += this.scores.get(i);
}
return sum / this.scores.size();
}
}
Basically I want to be able to have an object for students where they have their student number and their scores. This is so that I can give them an average.
However, it seems that I've done something wrong in reading the file in (Haven't ever done this before), because the String studentText = scoresFileReader.nextLine(); line throws me an error that states : Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
at MySchool.main(MySchool.java:22)
If it's any help, the three student codes and their scores print out the way they should before I get this error.
Can anyone help me to get this up and running? I'm not sure how to resolve it
EDIT:
I've actually noticed the issue to be that somehow numberOfStudents is being set to 51 when there's no 51 in the data. Even if I run the code below, it prints the first value of headerRow confirming that it is 3, which is correct. The when I use the same code to assign it to numberOfStudents suddenly it's become 51 when it prints again?
import java.io.File; // Import the File class
import java.io.FileNotFoundException; // Import this class to handle errors
import java.util.ArrayList;
import java.util.Scanner; // Import the Scanner class to read text files
public class MySchool {
public static void main(String[] args) {
int numberOfStudents;
ArrayList<Student> allStudents = new ArrayList<Student>() ;
// grab first line only, and check if first target is integer, or string
try {
File scoresFile = new File("Scores.txt");
Scanner scoresFileReader = new Scanner(scoresFile);
String headerRow = scoresFileReader.nextLine();
System.out.println(headerRow.charAt(0));
numberOfStudents = headerRow.charAt(0);
System.out.println(numberOfStudents);
for (int studentI = 0; studentI < numberOfStudents; studentI++) {
String studentText = scoresFileReader.nextLine();
System.out.println(studentText);
Student student = new Student(studentText);
allStudents.add(student);
}
scoresFileReader.close();
} catch (FileNotFoundException e) {
System.out.println("An error occurred");
e.printStackTrace();
}
float highestAverage = 0;
String highestScoringStudentNumber = null;
for (Student student : allStudents) {
if (student.getAverageScore() > highestAverage) {
highestAverage = student.getAverageScore();
highestScoringStudentNumber = student.getStudentNumber();
}
}
System.out.println("Highest scoring student: " + highestScoringStudentNumber);
}
}
The problem comes from the fact that you're actually reading an ASCII code of the char, not the value itself - '3' == 51. You need to convert the character to the correct value. The simpliest way is to use Character.getNumericValue(), eg.:
char c = headerRow.charAt(0);
numberOfStudents = Character.getNumericValue(c);

why isn't the rest of my method being called? (loop being ignored)

i'm trying to write a program that reads a file and then prints it out and then reads it again but only prints out the lines that begin with "The " the second time around. it DOES print out the contents of the file, but then it doesn't print out the lines that begin with "The " and i can't figure out why. it prints out the println line right before the loop, but then it ignores the for-loop completely. the only difference between my findThe method and my OutputTheArray method is the substring part, so i think that's the problem area but i don't know how to fix it.
import java.util.*;
import java.io.*;
public class EZD_readingFiles
{
public static int inputToArray(String fr[], Scanner sf)
{
int max = -1;
while(sf.hasNext())
{
max++;
fr[max] = sf.nextLine();
}
return max;
}
public static void findThe(String fr[], int max)
{
System.out.println("\nHere are the lines that begin with \"The\": \n");
for(int b = 0; b <= max; b++)
{
String s = fr[b].substring(0,4);
if(s.equals("The "))
{
System.out.println(fr[b]);
}
}
}
public static void OutputTheArray(String fr[], int max)
{
System.out.println("Here is the original file: \n");
for(int a = 0; a <= max; a++)
{
System.out.println(fr[a]);
}
}
public static void main(String args[]) throws IOException
{
Scanner sf = new Scanner(new File("EZD_readme.txt"));
String fr[] = new String[5];
int y = EZD_readingFiles.inputToArray(fr,sf);
EZD_readingFiles.OutputTheArray(fr,y);
int z = EZD_readingFiles.inputToArray(fr,sf);
EZD_readingFiles.findThe(fr,z);
sf.close();
}
}
this is my text file with the tester data (EZD_readme.txt):
Every man tries as hard as he can.
The best way is this way.
The schedule is very good.
Cosmo Kramer is a doofus.
The best movie was cancelled.
Try cloning sf and passing it to the other function.
Something like this:
Scanner sf = new Scanner(new File("EZD_readme.txt"));
Scanner sf1 = sf.clone();
int y = EZD_readingFiles.inputToArray(fr,sf);
EZD_readingFiles.OutputTheArray(fr,y);
int z = EZD_readingFiles.inputToArray(fr,sf1);
EZD_readingFiles.findThe(fr,z);
sf.close();
sf1.close();

error: class HackerRank is public, should be declared in a file named HackerRank.java

While submitting code on HackerRank, I am getting this compilation error:
error: class HackerRank is public, should be declared in a file named HackerRank.java
How can I get rid of it? I have tried changing the name of the class to main, but still it gives me the same compilation error.
import java.io.IOException;
import java.util.Scanner;
public class HackerRank {
public static void main(String a[]) throws IOException, Exception {
Scanner in = new Scanner (System.in);
int test = in.nextInt();
Scanner in1 = new Scanner(System.in);
if (test < 1 || test > 10) {
throw new Exception("Illegal test cases");
}
while (test-- > 0) {
// System.out.println("Enter patient dna");
String patient = in1.nextLine().toLowerCase();
// System.out.println("Enter virus dna");
String virus = in1.nextLine().toLowerCase();
int l = virus.length();
int i = 0;
int count = 0;
if (patient.length() > 100000 || virus.length() > 100000) {
throw new Exception("Input length out of bounds");
}
for (i = 0; i < patient.length() - virus.length(); i++) {
String sub = patient.substring(i, i + l);
count = 0;
for (int j = 0; j < sub.length(); j++) {
if (virus.charAt(j) != sub.charAt(j)) {
count++;
}
}
if (count == 0 || count == 1) {
System.out.print(i + " ");
}
}
System.out.println();
}
}
}
Only one class can be declared public within a file and his name must coincide with the file name ( without the extension ).
Try renaming your file to HackerRank.java.
Alternatively, you can change your public class' name:
public class YourFileName{
...
}
Java requires that each public class have its own file, and that the name of the file match the name of the public class it contains. If your file is not called "HackerRank.java", try renaming it to that and see if your error goes away.
The problem you are facing may be for this two reasons
Your class HackerRank is public so may be your file name is not the same as your class name. Your file name must be HackerRank.java
Or may be you have two classes in the same file and both are public.
Name your class as Solution, hackerrank provides an environment as specified in this link.
import java.io.IOException;
import java.util.Scanner;
public class Solution {
...
}

Java Scanner issues, Notecard class

I am trying to make a program that is basically virtual notecards. Each notecard has a string for a question and an answer as well as a count for now many times it has been asked. I am using a scanner in many instances and I think i am using it incorrectly, and am not quite sure why. The program will let me answer the first 2 questions, tell me they are incorrect no matter what, and skip letting me answer the last one. Here is the notecard class:
public class Notecard {
public String ans;
public String q;
public int count;
public Notecard(String q, String ans) {
this.q = q;
this.ans = ans;
this.count = 0;
}
public Boolean answer(String effort) {
if (this.q.toUpperCase().equals(effort.toUpperCase())) {
System.out.println("Correct!");
return true;
} else {
System.out.println("Incorrect! Correct answer:" + this.ans);
count++;
return false;
}
}
public void clearCount() {
this.count = 0;
}
public String getQ() {
return this.q;
}
}
and here is my other file:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import java.util.Scanner;
public class CreateNotecard {
int trys;
public static void main(String[] args) {
System.out.println("Get ready to be quizzed \n\n");
ArrayList<Notecard> notecards = makeCards();
quiz(notecards);
}
static ArrayList<Notecard> makeCards() {
ArrayList<Notecard> notecards = new ArrayList<Notecard>();
try {
BufferedReader in = new BufferedReader(new FileReader(
"notecards.txt"));
String str;
str = in.readLine();
while ((str = in.readLine()) != null) {
String[] argg = str.split(",");
notecards.add(new Notecard(argg[0], argg[1]));
}
in.close();
} catch (IOException e) {
System.out.println("File Read Error");
}
return notecards;
}
static void quiz(ArrayList<Notecard> notecards) {
ArrayList<Notecard> backupList = notecards;
Scanner sc = new Scanner(System.in);
long seed = System.nanoTime();
Collections.shuffle(notecards, new Random(seed));
int total = notecards.size();
int correct = 0;
for (Notecard x : notecards) {
System.out.println(x.getQ());
String effort = sc.next();
Boolean nailedIt = x.answer(effort);
if (nailedIt) {
correct++;
}
}
System.out.println("Total Notecards: " + total + "\nTotal Correct: "
+ correct);
System.out.println("Accuracy: " + (correct / total));
System.out.println("Do you want to repeat? Put \"y\" or \"n\"");
String choice1 = sc.nextLine();
if (choice1.toUpperCase().equals("Y")) {
System.out.println("Use only cards missed or all? Type \"missed\" or \"all\"");
String choice2 = sc.nextLine();
if (choice2.toUpperCase().equals("MISSED")) {
quiz(notecards);
} else {
quiz(backupList);
}
} else {
return;
}
}
}
I have a text file which I am using for this program, it contains
19-9,10
square root of 4,2
capitol of Missouri,Jefferson City
Blastoise's 1st evolution,squirtle
and my output is
Get ready to be quizzed
square root of 4
2
Incorrect! Correct answer:2
capitol of Missouri
Jefferson City
Incorrect! Correct answer:Jefferson City
Blastoise's 1st evolution
Incorrect! Correct answer:squirtle
Total Notecards: 3
Total Correct: 0
Accuracy: 0
Do you want to repeat? Put "y" or "n"
You are comparing the wrong things:
public Boolean answer(String effort) {
if (this.q.toUpperCase().equals(effort.toUpperCase())) {
Should be
if (this.ans.toUpperCase().equals(effort.toUpperCase())) {
The problem is that the Scanner class is looking for a delimiter to create tokens with, which is by default whitespace. Since you enter "2", the Scanner.next() finds no delimiters, so no token.
For example, if you enter "Jefferson City", the Scanner found one delimiter, so two tokens. sc.next in that case would be "Jefferson" only (no "City", that's the next token).
Solution? Read the line from stdin and using sc.nextLine()

CS106A handout 6 Exception java.lang.NullPointerException

Got an Error with NullPointerException . (cs106A handout 6 - Name Count using hash map)
Debugger told me the problem located # String input variable. I got no idea how to solve it.
thanks for reading.
import acm.io.*;
import acm.program.*;
import acm.util.*;
import java.util.*;
import java.io.*;
import java.io.BufferedReader.*;
import java.lang.*;
public class NameCounts extends ConsoleProgram{
// hashmap
static HashMap<String,Integer> myUniq = new HashMap<String,Integer>();
static String input ;
static public void insertName(){
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while(true){
System.out.println("Enter name:");
// if keyboard input contain new unique name ,
// store it in the hashmap and count the value +1
input = br.readLine();
if(input.equals("")) break;
if( myUniq.containsKey(input) ==false){
Integer temp = myUniq.get(input);
temp = temp + 1;
myUniq.put(input,temp);
}
}
}
catch (IOException e){ };
}
// print and show every single hash map and count value
static public void releaseUnique(){
for(int i= 1 ; i < myUniq.size() ; i++){
System.out.println("Entry"+"[" + input + "]"+"has count"+myUniq.get(input));
}
}
public static void main (String[] args){
insertName();
releaseUnique();
}
}
I think you should change
if( myUniq.containsKey(input) ==false){
Integer temp = myUniq.get(input);
temp = temp + 1;
myUniq.put(input,temp);
}
to
if(myUniq.containsKey(input)) {
Integer temp = myUniq.get(input);
temp = temp + 1;
myUniq.put(input, temp);
} else {
myUniq.put(input, 1);
}

Categories

Resources