I submitted this code to the KATTIS online code tester. It's supposed to return the difference of two numbers that have been given repeatedly until it reaches an EOF. It works just fine in eclipse, but KATTIS says that "An exception was not caught". I was hoping for some help as to what exception has not been caught.
The imports and class "Kattio" were provided so the input and output would always work with the online code system.
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStream;
class Kattio extends PrintWriter {
public Kattio(InputStream i) {
super(new BufferedOutputStream(System.out));
r = new BufferedReader(new InputStreamReader(i));
}
public Kattio(InputStream i, OutputStream o) {
super(new BufferedOutputStream(o));
r = new BufferedReader(new InputStreamReader(i));
}
public boolean hasMoreTokens() {
return peekToken() != null;
}
public int getInt() {
return Integer.parseInt(nextToken());
}
private BufferedReader r;
private String line;
private StringTokenizer st;
private String token;
private String peekToken() {
if (token == null)
try {
while (st == null || !st.hasMoreTokens()) {
line = r.readLine();
if (line == null) return null;
st = new StringTokenizer(line);
}
token = st.nextToken();
} catch (IOException e) { }
return token;
}
private String nextToken() {
String ans = peekToken();
token = null;
return ans;
}
}
public class Hello {
public static void main(String[] args) {
Kattio io = new Kattio(System.in, System.out);
while (io.hasMoreTokens()){
int n1 = io.getInt();
int n2 = io.getInt();
if (n1>n2){
io.println(n1-n2);
}
else if (n2>n1){
io.println(n2-n1);
}
else {
io.println("0");
}
}
io.close();
}
}
just a guess.
Look for exception in your code with different types of data. If a line with non integer your program will terminate. It should probably look for next token?
Please modify your main() by adding try/catch like so:
public static void main(String[] args) {
try {
Kattio io = new Kattio(System.in, System.out);
while (io.hasMoreTokens()){
int n1 = io.getInt();
int n2 = io.getInt();
if (n1>n2){
io.println(n1-n2);
}
else if (n2>n1){
io.println(n2-n1);
}
else {
io.println("0");
}
}
io.close();
} catch(Exception e) { e.printStackTrace(); }
}
Normally you would want more localized exception handling but this will at least allow you to copy-paste us the stacktrace so we can see it.
I am unfamiliar with the Kattis online code tester but assume it checks for unchecked exceptions that may be thrown (an uncaught checked exception would cause the code not to compile). I can't see anywhere in the code that checks that the next token is an Integer, so if Integer.parseInt tries to parse something which isn't an integer, it will throw a NumberFormatException.
Depending on the audience for your application, you could leave this as it is (if the audience is java developers who will understand that exception) or catch it rethrow something more user-friendly (if they are not).
public int getInt() {
// not tested
int nextInt;
try {
nextInt = Integer.parseInt(nextToken());
} catch (NumberFormatException nfe) {
throw new RuntimeException("Invalid number in file");
}
return nextInt;
}
Presumably though, the code tester would still complain though as it's throwing another (more user-friendly) exception :-)
Related
I have this code snippet that uses OpenCSV:
class Pojo {
#CsvBindByName(column="point")
Integer point;
#CsvBindByName(column="name")
String name;
}
And:
class Main {
readFile(){
CsvReader reader = new Csv(.....);
CsvToBean<Pojo> bean = new CsvToBeanBuilder<Pojo>(reader)...;
List<Pojo> list = bean.parse();
}
}
Why is it - while parsing - not considering header coming with zwnbsp and that column value I am getting as null?
Example input data:
ZWNBSPpoint
Not a real answer, yet a potential workaround for you, in case all CSV files to be processed share the extra zwnbsp character at the very beginning of the input (file).
In Pojo switch to:
#CsvBindByName(column="\uFEFFpoint")
Integer point;
Given input data
var input = "\uFEFFpoint,name\n1,A";
And
CSVReader csvReader = new CSVReader(new StringReader(input));
List<Pojo> beans = new CsvToBeanBuilder<Pojo>(csvReader)
.withType(Pojo.class)
.withIgnoreLeadingWhiteSpace(true)
.build()
.parse();
System.out.println(beans);
This will produce a valid Pojo[point = 1, name = A].
I tested the above scenario with OpenCSV version 5.7.1, with Java 17 under MacOS.
Without the above adjustment to the mapping annotation ("point" -> "\uFEFFpoint"), CSVReader will interpret the extra UTF-8 symbol \uFEFF as an extra character for the mapping to the field point which will produce a mismatch finally resulting in a non-populated field value.
However, it seems to be incorrect/invalid CSV input, as others already pointed out in the comments below your question. OpenCSV does not seem to have a flag or switch for HeaderColumnNameMappingStrategy to circumvent such cases as reported by you.
Apologies for misleading you and for some strange reason, missing the BOM problem. This is not extensively tested, but works:
package com.technojeeves.opencsvbeans;
import com.opencsv.bean.CsvToBeanBuilder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.List;
import java.io.IOException;
import java.io.Reader;
import java.io.FilterReader;
public class App {
public static void main(String[] args) {
try {
System.out.println(new App().read(Path.of(args[0])));
} catch (Throwable t) {
t.printStackTrace();
}
}
public List<Pojo> read(Path path) {
try (Reader reader = new BomFilterReader(Files.newBufferedReader(path))) {
//try (Reader reader = Files.newBufferedReader(path)) {
return new CsvToBeanBuilder(reader).withType(Pojo.class).build().parse();
} catch (IOException e) {
throw new RuntimeException("Cannot read file: " + path.toFile().getName() + e);
}
}
}
class BomFilterReader extends FilterReader {
public static final char BOM = '\uFEFF';
private boolean haveReadBOM = false;
public BomFilterReader(Reader in) {
super(in);
}
#Override
public int read() throws IOException {
int c = super.read();
if (!haveReadBOM && ((char)c == BOM)) {
return super.read();
}
haveReadBOM = true;
return c;
}
#Override
public int read(char[] a) throws IOException {
return read(a, 0, a.length);
}
#Override
public int read(char a[], int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, a.length);
if (len == 0) {
return 0;
}
int c = read();
if (c == -1) {
return -1;
}
a[off] = (char) c;
int i = 1;
try {
for (; i < len; i++) {
c = read();
if (c == -1) {
break;
}
a[off + i] = (char) c;
}
} catch (IOException ee) {
}
return i;
}
}
I came up with the following code to read information from a file:
import java.io.*;
import java.util.*;
public class Reader {
private Scanner s;
public void openFile() {
try {
s = new Scanner(new File("file.txt"));
} catch (Exception e) {
System.out.println("File not found. Try again.");
}
}
public void readFile() {
while (s.hasNext()) {
String a = s.next();
String b = s.next();
String c = s.next();
int d = s.nextInt();
int e = s.nextInt();
int f = s.nextInt();
}
public void closeFile() {
s.close();
}
}
However, I get a NullPointer error on the (while (s.hasNext())) line and can't find a solution.
I'm working in Eclipse and the file I'm reading from is imported correctly into the project so that should not be an issue.
EDIT:
The way I access the methods:
public class Tester {
public static void main(String[] args) {
Reader read = new Reader();
read.openFile();
read.readFile();
read.closeFile();
}
}
As per the statement where NPE throws, while (s.hasNext()), it's most probable that the s is null pointer, you can add System.out.println(s); before that statement to double confirm it.
And for the reason why the s is null, there are two possible reasons:
You didn't invoke openFile before readFile
Exception is thrown when you open the file. The s is only a declaration and hasn't pointed to any object yet.
Maybe for a better practice, you can assert whether a instance is null or not before invoking its method. And as per my understanding, the readFile depends on the result of openFile, maybe you can set return value of openFile like a boolean value and check the return value before further open file operation. It's impossible to read a file which can't be even open, right?
import java.io.*;
import java.util.*;
public class Reader {
private Scanner s;
public boolean openFile() {
try {
s = new Scanner(new File("file.txt"));
return true;
} catch (Exception e) {
System.out.println("File not found. Try again.");
return false;
}
}
public void readFile() {
while (s.hasNext()) {
String a = s.next();
String b = s.next();
String c = s.next();
int d = s.nextInt();
int e = s.nextInt();
int f = s.nextInt();
}
}
The invoker can do something like below:
Reader reader = new Reader();
if (reader.openFile())
reader.readFile();
Suppose that file.txt only contains "Hello". When I compile the Java code, it shows
Error: This method must return a result of type java.lang.String in line5.
When I print in readTxt function, that works, it can show "Hello".
I already check the result is correctly String type, but it also shows compiler error. How can I make the return value to the main function?
import java.io.*;
import java.lang.String;
public class ReadTxtFile {
public static String readTxt(String filePath) {
try {
File file = new File(filePath);
if(file.isFile() && file.exists()) {
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "utf-8");
BufferedReader br = new BufferedReader(isr);
String lineTxt = null;
lineTxt = br.readLine();
//System.out.println(lineTxt);
br.close();
return lineTxt;
} else {
}
} catch (Exception e) {
}
}
public static void main(String[] args) {
String filePath = "C:/file.txt";
String fileword = readTxt(filePath);
System.out.println(fileword);
}
}
You promised to return a String from your method, so you now have to do that. The only way around that promise is to throw an exception.
public static String readTxt(String filePath) { // Here you promise to return a String
try {
...
if(file.isFile() && file.exists()) {
...
return lineTxt; // Here you return a String as promised
} else {
// Here you're missing either return or throw
}
} catch (Exception e) {
// Here you're missing either return or throw
}
}
This is fundamentally a design problem - what should your method do if it fails to read the file for some reason? Return a special string like "Error"? Return null? Fail and throw and exception? Something else?
Answer that to yourself and it will be clear to you how to fix the code.
There are several best practices you should follow that will prevent future error. I have tried to cover them. Not saying mine is the perfect one, but you will get the idea.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class StackOverFlow {
public static void main(String[] args) {
try {
String sText = getFileText("C:/file.txt");
System.out.println("Text is: " + sText);
} catch (FileNotFoundException e) {
System.out.println("File not Found");
} catch (IOException e) {
System.out.println("#Error while reading text: " + e.getMessage());
}
}
private static String getFileText(String filePath) throws FileNotFoundException, IOException {
File file = new File(filePath);
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(file));
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
reader.close();
}finally {
reader.close();
}
return new String(stringBuilder);
}
}
Hey guys I have a problem, I would like to assert that when I input 2 specific strings that an array is returned. I want to use the assert statement and parameterized testing to do this however my current assert statement is showing an error, I have placed my code below please help:
My inputs are both String data type and my output from the drop course is an array
import IT_chatbot.drop_course;
#RunWith(Parameterized.class)
public class drop_course_test {
drop_course check;
#Before
public void setUp() throws Exception {
check= new drop_course();
}
private String[] output;
private String input1;
private String input2;
public drop_course_test(String output[],String input1,String input2 )
{
this.output=output;
this.input1=input1;
this.input2=input2;
}
#Parameters
public static Collection testConditions(){
String[] droplist1={"ITE222 Web Development 2","ITE365 Software Quality Management","ITE446 Current Topics in Software Engineering","ITE220 Programming 1"};
return Arrays.asList(new Object [][]{
{droplist1, "216110116","ITE200"},
});
}
#Test
public void test() {
assertEquals(output, drop_course.drop(input1, input2));
}
}
The method i am trying to test can be seen below:
package IT_chatbot;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class drop_course {
public static String[] drop(String studentID, String courseCode){
String filePath = "enrolled_courses"+studentID+".txt";
String disenrolled_subtracted[]=new String[5];
int value_at=0;
System.out.println("Your Course has been dropped the following are your current courses:");
try {
BufferedReader lineReader = new BufferedReader(new FileReader(filePath));
String lineText = null;
while ((lineText = lineReader.readLine()) != null) {
if(lineText.contains(courseCode)){
lineText = lineText.replace(lineText, "");
FileWriter writer = new FileWriter("filePath", true);
writer.write("-disenrolled-"+lineText);
}else{
System.out.println(lineText);
disenrolled_subtracted[value_at]=lineText;
value_at=value_at+1;
}
}
lineReader.close();
} catch (IOException ex) {
System.err.println(ex);
}
return disenrolled_subtracted;
}
Use Method
Assert.assertArrayEquals( expectedResult, result );
Instead of
assertEquals
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I have a small assignment for uni which I seem to be stuck with. The application is suppose to be a quiz program which reads questions and answers from a text files and stores them like a flash card. My problem is that my buffered reader seems to be returning the nullPointer exception when it tries to read from the file. I'm unsure why this is. I will provide all code and highlight the error in bold. After doing a bit of debugging I found that the readLine method was returning null. Any thoughts? Thanks a lot. Error is at String[] line = getLine().split(":");
text file is in the format question:answer
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
public class Quiz {
private ArrayList<FlashCard> flashCards;
public static void main(String[] args){
Quiz quiz1 = new Quiz();
}
public Quiz(){
FlashCardReader cardReader = new FlashCardReader();
try {
if(cardReader.isReady()==true){
flashCards = cardReader.getFlashCards();
play();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void play(){
Scanner userInput = new Scanner(System.in);
String answer = userInput.nextLine();
for(FlashCard card: flashCards){
System.out.println(card.getQuestion());
System.out.println("********************");
sleep(10000);
System.out.println("Enter your answer:");
answer = userInput.nextLine();
if(card.getAnswer() == answer){
System.out.println("Correct.");
}else{
System.out.println("Incorrect. The correct answer is " + card.getAnswer() + ".");
}
}
}
private void sleep(int x){
try {
Thread.sleep(x);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class FlashCardReader {
BufferedReader reader;
public FlashCardReader(){
try {
reader = new BufferedReader(new FileReader("Questions.txt"));
} catch (FileNotFoundException e) {
System.err.println(e.toString());
}
}
public String getLine() throws IOException{
return reader.readLine();
}
public Boolean isReady() throws IOException{
return reader.ready();
}
public ArrayList<FlashCard> getFlashCards(){
ArrayList<FlashCard> flashcards = new ArrayList<FlashCard>();
try {
for(int i = 1; i <= reader.lines().count(); i++){
**String[] line = getLine().split(":");**
System.out.println(line[0]);
flashcards.add(new FlashCard(line[0],line[1]));
}
} catch (IOException e) {
System.err.println(e);
e.printStackTrace();
}
return flashcards;
}
}
public class FlashCard {
private String question;
private String answer;
public FlashCard(String question, String answer){
this.question = question;
this.answer = answer;
}
public String getQuestion(){
return question;
}
public String getAnswer(){
return answer;
}
}
How about changing the for loop to while loop to avoid null condition. As you cannot be sure that your code starts from line one as you expect by assigning i to 1.
String lines ;
while((lines = getLine()) != null){
String[] lineArray = lines.split(":");
System.out.println(lineArray[0]);
flashcards.add(new FlashCard(lineArray[0],lineArray[1]));
}