Java Input Mismatch Exception with a specialized txt file - java

I am working on a program and I need to scan in a txt file. The txt file is guaranteed to follow a particular format in terms up where and when different types occur. I try to take advantage of this in my program and use a scanner to put the parts I know are ints into ints, along with doubles and strings. When I run my program It tells me I have a type mismatch exception, I know that due to the formatting of the txt file that all my types match up so how do I make the IDE think this is okay. Here's a block of the problematic code is that helps.
ArrayList<Student>studentList=new ArrayList<Student>();//makes a new Array list that we can fill with students.
FileInputStream in=new FileInputStream("studentList.txt");//inputs the text file we want into a File Input Stream
Scanner scnr=new Scanner(in);//Scanner using the Input Stream
for(int i=0;i<scnr.nextInt();i++)//we know the first number is the number of minor students so we read in a new minor that number of times
{
Undergrad j=new Undergrad();//make a new undergrad
j.setDegreeType("MINOR");//make the degree type minor because we know everyone in this loop is a minor.
j.setFirstName(scnr.next());//we know the next thing is the student's first name
j.setLastName(scnr.next());//we know the next thing is the student's last name
j.setID(scnr.nextInt());//we know the next thing is the student's ID
j.setGPA(scnr.nextDouble());//we know the next thing is the student's GPA
j.setCreditHours(scnr.nextDouble());//we know the next thing is the student's credit hours
studentList.add(j);//Finally, we add j to the arraylist, once it has all the elements it needs
}

Computer programs do exactly what you tell them to do.
If you create a program that expects certain input, and that program tells you "unexpected input"; then are exactly two logical explanations:
Your assumption about the layout of the input (that you put in your program) were wrong
The assumptions are correct, but unfortunately the input data doesn't care about that
Long story short: it is not the IDE that gets things wrong here.
Thus the "strategy" here is:
open your text file in an editor
open your source code in your IDE
Run a debugger; or "run your code manually"; meaning: walk through the instructions one by one; and for each scanner operation, check what the scanner should return; and what the file actually contains in that place

Related

ArrayList<Integer> is not storing user-inputted integers in Java 8 (1.8)

*EDIT - SOLVED: After instantiating the Scanner Object, I used a delimiter as follows:
scanner.useDelimiter("");
Prior to this, I did try a delimiter that looked something like this (the exact code is available on Stack Overflow):
scanner.useDelimiter("\\p{javaWhitespace}");
...but it didn't work very well.
Thank you, everyone. If you're having this very same issue, try the first delimiter. If it doesn't work, upgrade your JDK to 13 then try it again.
Ok, my goal is to have a user input a credit card number which I would then like to store in an ArrayList of Integers and subsequently pass this list to my functions which will perform the Luhn algorithm in order to validate the provided number. Once the user presses Enter, the processing begins. This is a console application, nothing fancy.
Everything works beautifully...except the user-input part. None of the user-input is being stored into the declared ArrayList. I've inserted a print message to give me the size of the list just after the pertinent while-loop and....yep, 0. I also pass this list into a custom lengthChecker(ArrayList<Integer> list){} function subsequent to the relevant while-loop and it's printing my custom error-message.
I have declared local int variables within the scope of the while-loop and that wasn't helping much. I have tried getting the user's input as Strings and storing them in an ArrayList<String> list; then parsing the input but that didn't work very well (especially as I need the Enter key to behave as a delimiter such that the next steps can take place)
Anyways, here is the code to the function in question. Am I missing something obvious or should I just quit programming?
public void userInput() {
Scanner scanner = new Scanner(System.in);
List<Integer> list = new ArrayList<Integer>();
System.out.println("Please input the card-number to be checked then press Enter: ");
while(scanner.hasNextInt()) {
list.add(scanner.nextInt());
}
System.out.println("Length of list: " + list.size());
listLengthChecker(list);
scanner.close();
}
Thank you in advance.
I don't have the full context on all the code you've written to be able to solve your problem, but I can guess at what's going on. If you want to run any user I/O (such as the scanner), it must occur within the main method. I can only assume that you run your userInput() function within the main method in your class. However, because your userInput() function doesn't have the static keyword in its definition, it can't be accessed without initialising an object of the class - but as far as I can tell from your code, there is no object that the method could refer to. Add the static keyword (i.e. initialise the method as public static void userInput()) to be able to run the function as you intend.
As for the while loop - there's a small chance that this is a difference in Java versions (I use Java 11), but while(scanner.hasNextInt()) won't stop being true at the end of your line or when you press enter - only when you insert something (such as a character) that cannot be interpreted as an integer.
This while loop untill you enter any non integer value.
You finished entering all the integer values and then your program will print your list elements.

Is there a way to edit data on a text file without having to create another temporary file in Java?

Suppose I've a couple of objects' values stored on a text file. In the beginning, there will be some values which will have the same value, for instance, all students by default will have 0 age. Now if I want to make an edit in the age of one student using the conventional file handling approach, I'll end up making changes to all other students who have 0 age, while writing my data onto the temporary file. Thus, I was hoping that if there is a better way to make changes to a file using file handling in java. Just to give an example of the issue at hand consider the following text file
Edsger
Dijkstra
123
72 years
Ruth
Dijkstra
12345
29 years
The line indicates a space between the age and the name. Now, my task is to construct a program where a user can change any detail, such as the First Name, surname, roll_number or the age. As you can see from the example given above, two people can share some data that is common. In this case, it is the surname. However, the roll number (123,12345) will always be unique. The problem comes when you have to change similar data. Suppose the user wants to edit the surname. Then by I would create a temporary file which would hold this data and later I would read this data with some conditions to it. So the code might look like this:
Note: This data is stored at a known location "abc.txt".
BufferedReader br=new BufferedReader(new FileReader("abc.txt"));
BufferedWriter bw=new BufferedWriter(new FileWriter("Temp.txt"));
String a=br.readLine();
while(a!=null)
{ bw.write(a);
bw.newLine();
a=br.readLine();
}
br.close();
bw.close();
BufferedReader br1=new BufferedReader(new FileReader("Temp.txt"));
BufferedWriter bw1=new BufferedWriter(new FileWriter("temp.txt"));
String b=br1.readLine();
while(b!=null)
{
if(b.equals(requested_surname))
bw1.write(w);//w is the String that holds the altered surname as desired by the User, for the sake of an example say it is Euler
else
bw1.write(b);
bw1.newLine();
b=br1.readLine();
}
bw1.close();
br1.close();
f.delete();
As a result the Original text file "abc.txt" will show something like this:-
Edsger
Euler
123
72 years
Ruth
Euler
12345
29 years
Now this will be a bungling problem as I intend to change only Ruth's surname! I know that this is slightly different from what I initially asked, but I think that if I could target the line below "Ruth", I can make the desired changes.
Please Help...
There are several approaches to do this.
You could store the data in a csv file, 1 line for each object:
123,Edsger,Dijkstra,72
12345,Ruth,Dijkstra,29
4567,Ruth,Euler,27
Then, on program start-up read all the objects in memory (in a structure) for easy access. On program exit or save, write everything back to the file (assuming the number of objects isn't really big - i.e. not millions).
Another way is to store every field of the object as a fixed width value:
123 Edsger Dijkstra 72
12345 Ruth Dijkstra 29
4567 Ruth Euler 27
That way changes to the data can easily be written 'in place' in the file. You only have to make sure the fields don't exceed the maximum size. The number fields could even be in binary format if needed.
With fixed width, or an exact size for each object, it is easy (and faster) to look up a certain object or roll number: since the size of the objects is known, file seek can be used to jump directly to the beginning of each object - no parsing is needed.
Note: the objects don't need to be on a separate line in this case (I've done it for clarity) - but if they are, newlines (could be \r or \r\n or \n) will have to be added to the size of the objects.
Of course, searches for a certain person/object should always be done on a unique ID, in this case roll number, never on the name.
File can be thought as a character array.
char[] file = ... // file (on disk)
char[] newData = ... // data to be written
int pos = ... // the position in the file to write to
for (i=0; i<newData.; i++) {
file[pos+i] = newData[i];
}
You can particularly make use of seek().
Check this out as well:
http://docs.oracle.com/javase/tutorial/essential/io/rafs.html

Java- Scanner is not reading String properly

I am writing a program for a school project in which I read a .csv file and perform calculations based on the data within it.
System.out.println("Please enter a second data set to search:\nFor example, type 'narcotics, poss,' 'criminal damage,' or 'battery.'\nCapitalization does not matter.");
secondDataSet = scan.nextLine().toUpperCase();
System.out.println("Searching for instances of " + secondDataSet);
if (!secondDataSet.equals(""))
{
while (inputStream.readLine() != null)
{
String[] all = line.split(splitBy);
if (all[8].toUpperCase().equals("TRUE"))
{
numArrests++;
}
if (all[8].toUpperCase().equals("FALSE"))
{
numNonArrests++;
}
if (all[5].equals(secondDataSet))
{
secondDataCount++;
}
numberOfLines++;
line = inputStream.readLine();
}
if (secondDataCount == 0)
{
i--;
System.out.println("The data set you entered does not exist.\nPlease try checking your spelling or reformatting your response.");
}
The above is part of my code I am using that contains my Scanner problems. I am reading a .csv containing the Chicago arrest records for the past several years. Every time I run the program, however, it skips past the scan.nextLine(). It just executes my print statement "Please enter a second data set..." and then prints out "Searching for instances of ".
I am using jGRASP, and my compiler looks like:
Please enter a data set to search:
For example, type 'narcotics, poss,' 'criminal damage,' or 'battery.'
Capitalization does not matter.
Searching for instances of
And it loops four times without getting user input. I tried using scan.next() instead, but that did not work when I input a String with two words because some there are some values in the .csv like "CRIMINAL DAMAGE" and scan.next() searched for the words "CRIMINAL" and "DAMAGE" separately. If someone has any suggestions on how to make the computer stop to read the scan.nextLine(), use scan.next() to read two words, or any other solution to this I would appreciate it.
I am extremely confused by this at the moment so any help would be very nice as I've spent an enormous amount of time on a small part of a large project that I need to complete... Also, I can clarify any questions you may have if my question is unclear or vague.

General advice? GUI with Buffered Reader/Writer for ACH in JAVA

I posted here a few weeks ago regarding a project I have for work. The project began as creating a simple little program that would take an incoming ACH file and read each line. The program would also ask a user for a "reason code" and "bank" which would affect the next step. The program would then reformat all the data in a certain way and save it to an external file. For those that don't know, an ACH is simply a text based file that is in a very concrete format. (Every character and space has a meaning.)
I have completed that task using a few GUI items (Jcombobox, JFileChooser, etc), string array lists, buffered reader/writer, and lots of if/else statements.
The task has now been expanded to a much more complicated and I don't know exactly how to begin, so I thought I would seek the communities advice.
When an ACH file comes in it will be in a format that looks something like this:
101 100000000000000000000000000000
522 00000202020382737327372732737237
6272288381237237123712837912738792178
6272392390123018230912830918203810
627232183712636283761231726382168
822233473498327497384798234724273487398
522 83398402830943240924332849832094
62723921380921380921382183092183
6273949384028309432083094820938409832
82283409384083209482094392830404829304
900000000000000000000000000000000
9999999999999999999999999999999999999
9999999999999999999999999999999999999
(I will refer to each line by " " number, for example "1 number" are the lines that begin with 1)
The end result is that the lines of data are maniuplated and put into "batches". The output file begins with the "1 number"
and then contains a batch with the format of
5
6
8
5
6
8
5
6
8
We continue using the same "5 number" until all sixes that were below it in the original file have been written, then we go to the next "5" and work with the "6" below it.
So, my project now is to create a full GUI. After the user inputs the file the GUI will have some type of drop down box or similar list of all the "6" numbers. For each number there should be another drop down box to choose the reason code (there are 7 reason codes).
Basically the ultimate objective is:
Display all the "6" numbers and give the user the ability to choose a reason code for each.
Allow the user to only select a certain amount of the "6" numbers if they wish.
Is it possible for me to do this using Buffered Reader/ Writer? I currently save the values into Array Lists using the following code:
while((sCurrentLine = br.readLine()) !=null)//<---------This loop will continue while there are still lines to be read.
{
if (sCurrentLine.startsWith("5")){//<------------------If the line starts with "5"..
listFive.add(sCurrentLine);//<-------------------------Add the line to the array list "listFive".
countFive++;//<---------------------------------------------Increase the counter "countFive" by one.
}else if (sCurrentLine.startsWith("6") && countFive==1){//<---------If the line starts with "6" and countFive is at a value of 1..
listSix.add(sCurrentLine);//<---------------------------------------Add the line to the array list "listSix".
}else if (sCurrentLine.startsWith("6") && countFive==2){//<-----------------If the line starts with "6" and countFive is at a value of 2..
listSixBatchTwo.add(sCurrentLine);//<--------------------------------------Add the line to the array list "listSixBatchTwo".
}else if (sCurrentLine.startsWith("6") && countFive==3){//<-----------------------If the line starts with "6" and countFive is at a value of 3..
listSixBatchThree.add(sCurrentLine);//<------------------------------------------Add the line to array list "listSixBatchThree".
}else if (sCurrentLine.startsWith("6") && countFive==4){//<------------------------------If the line starts with "6" and countFive is at a value of 4..
listSixBatchFour.add(sCurrentLine); //<--------------------------------------------------Add the line to array list "listSixBatchFour".
}else if (sCurrentLine.startsWith("8")){//<-----------------------------------------------------If the line starts with "8"..
listEight.add(sCurrentLine);//<----------------------------------------------------------------Add the line to array list "listEight".
}else if (sCurrentLine.startsWith("1")){//<-----------------------------------------------------------If the line starts with "1"..
one = sCurrentLine;//<-------------------------------------------------------------------------------Save the line to String "one".
}else if (sCurrentLine.startsWith("9") && count9 == 1){//<---------------------------------------------------If the line starts with "9" and count9 is at a value of 1..
nine = sCurrentLine;//<-------------------------------------------------------------------------------------Save the line to String "nine".
count9 = 0;//<--------------------------------------------------------------------------------------------------Set count9 to a value of 0.
}else if (sCurrentLine.startsWith("999") && count9 == 0){//<-----------------------------------------------------------If the line starts with "999" and count9 is at a value of 0..
listNine.add(sCurrentLine);//<---------------------------------------------------------------------------------------Add the line to array list "listNine".
}else{
}
}
If anyone can point me where I can get started I would be very grateful. If you need more information please let me know.
Update:
Here is an example of my JOptionPane with decision making.
String[] choices = {"Wells Fargo", "Bank of America", "CitiBank", "Wells Fargo Legacy", "JPMC"};
String input = (String) JOptionPane.showInputDialog(null, "Bank Selection", "Please choose a bank: ", JOptionPane.QUESTION_MESSAGE, null, choices, choices[0]);
if (input.equals("Wells Fargo"))
{
bank = "WELLS FARGO";
}else if (input.equals("Bank of America")){
bank = "BANK OF AMERICA";
}else if (input.equals("CitiBank")){
bank = "CITI BANK";
}else if (input.equals("Wells Fargo Legacy")){
bank = "WELLS FARGO LEGACY";
}else if (input.equals("JPMC")){
bank = "JPMC";
}
}else{
}
Let's assume I wanted to use the Buffered Writer to save all of the "6" numbers into a String array, then put them into a drop down box in the GUI. How could I accomplish this?
Can you use the input from Buffered Writer in a GUI..
Well, a BufferedWriter is not used to get input but rather to output information, but assuming that you meant a BufferedReader, then the answer is yes, definitely. Understand that a GUI and getting data with a BufferedReader are orthogonal concepts -- they both can work just fine independently of the other. The main issues involving reading in data with a Bufferedhaving a GUI
Say a JOptionPane for example.
I'm not sure what you mean here or how this relates.
If yes, then how could I go about doing that? In all the examples I have seen and tutorials about JOptionPane everything is done BEFORE the main method. What if I need if statements included in my JOptionPane input? How can I accomplish this?
I'm not sure what you mean by "everything is done before the main method", but it sounds like you may be getting ahead of yourself. Before worrying about nuts and bolts and specific location of code, think about what classes/objects your program will have, and how they'll interact -- i.e., what methods they will have.
I believe I just had an idea of how I need to proceed first. Can someone please verify? 1. Create static variables representing the lines that will be read. (Such as a static ArrayList.
No, don't think about static anything off the bat, since once you do that, you leave the OOP realm and go into procedural programming. The main data should be held in instance variables within a class or two.
Create the actual GUI, outside the main Method.
I'm not sure what you mean "outside the main method", but the GUI will consist of multiple classes, probably one main one, and an instance of the main class is not infrequently created in the main method, or in a method called by the main method, but queued onto the Swing event thread.
Create the Buffered Reader which will write to the variables mentioned in #1, inside the main method.
Again, I wouldn't do this. The main method should be short, very short, and its reason for existence is only to start your key objects and set them running, and that's it. Nothing critical (other than just what I stated) should be done in them. You're thinking small toy programs, and that's not what you're writing. The reader should be an instance variable inside of its own class. It might be started indirectly by the GUI via a control class which is a class that responds to GUI events. If you need the data prior to creation of the GUI, then you will have your main method create the class that reads in the data, ask it to get the data, and then create your GUI class, passing the data into it.

Handling an exception where more or less than 4 characters is entered

I'm writing a Mastermind program where it takes input for the guess, but I need to make sure that it only takes 4 characters of input. So if someone entered anything other than 4 characters, it would prompt for reentry. I know this isn't hard at all, I'm just drawing a blank and haven't been able to find an answer on here anywhere.
Lets try to do it, one step at a time.
Get user input in your program. If it's standard input, one way to pull it is with System.in, which is an InputStream.
Store the input in an intermediate variable. The type of this variable can be String.
If needed, cast the value to a type which is the most relevant to your application's requirement. Before that check input for bad values like null.
Perform the logic on the input, which in your case is finding out whether the length of the input is 4.
Prompt again for input if the current one doesn't meet the requirement. One way to do it is to put your relevant code in a loop which terminates only when you get the right input.
And if that doesn't work, you're most welcome to ask again including code that shows your effort.

Categories