Java .hasNextInt() mismatch exception - java

I have a .txt file that is formatted as follows
The Shawshank Redemption
100
19.95
DVD
There are many more lines, but I'm trying to store these values into four different ArrayLists. The problem is a get the error java.util.InputMismatchException. Here is my code:
while(list.hasNext() && !list.nextLine().equals("")){
titleList.add(list.nextLine());
quantityList.add(list.nextInt());
priceList.add(list.nextDouble());
typeList.add(list.nextLine());
}
The program crashes at quantityList.add(list.nextInt()); telling me that the next line is not and int, giving me that error. It will read it though if I use nextLine(). Any tips anyone can give me would be extremely helpful.

You have already read the first line in your while statement: -
while(list.hasNext() && !list.nextLine().equals(""))
And then when you again call nextLine first time, you are actually reading the integer (100), using list.nextLine and that is why you get that exception. Because you are probably now storing a String in an Integer List. Just remove that 2nd test from while.
2nd problem is that, you have checked list.hasNext() just once, and then you are reading 4 inputs. That may again throw you exception, if you go out of input. So, you also need to take care of that.
And another issue, which you will get is due to the usage of list.nextInt() and list.nextDouble(). Remember that, those methods read the input till the newline character at the end. So, the newline character left after reading will be read by the following invocation of method reading input, if not consumed. So, you also need to add an empty list.next() call after both of those methods, to consume the newline, so that newline is not read by list.nextDouble() used after list.nextInt(), else you will keep on getting exception.
Apart from those problems, I would suggest you to create a Class storing those attributes, and the have a List of objects of that class, rather than having 4 different lists.

Related

Java processing lines in file and data structures

I have read a bit about multidimensional arrays would it make sense to solve this problem using such data structures in Java, or how should I proceed?
Problem
I have a text file containing records which contain multiple lines. One record is anything between <SUBBEGIN and <SUBEND.
The lines in the record follow no predefined order and may be absent from a record. In the input file (see below) I am only interested in lines MSISDN, CB,CF and ODBIC fields.
For each of these fields I would like to apply regular expressions to extract the value to the right of the equals.
Output file would be a comma separated file containing these values, example
MSISDN=431234567893 the value 431234567893 is written to the output file
error checking
NoMSISDNnofound when no MSISDN is found in a record
noCFUALLPROVNONE when no CFU-ALL-PROV-NONE is found in a recored
Search and replace operations
CFU-ALL-PROV-NONE should be replaced by CFU-ALL-PROV-1/1/1
CFU-TS10-ACT-914369223311 should be replaced by CFU-TS10-ACT-1/1/0/4369223311
Output for first record
431234567893,BAOC-ALL-PROV,BOIC-ALL-PROV,BOICEXHC-ALL-PROV,BICROAM-ALL-PROV,CFU-ALL-PROV-1/1/1,CFB-ALL-PROV-1/1/1,CFNRY-ALL-PROV-1/1/1,CFNRY-ALL-PROV-1/1/1,CFU-TS10-ACT-1/1/1/4369223311,BAIC,BAOC
Input file
<BEGINFILE>
<SUBBEGIN
IMSI=11111111111111;
MSISDN=431234567893;
CB=BAOC-ALL-PROV;
CB=BOIC-ALL-PROV;
CB=BOICEXHC-ALL-PROV;
CB=BICROAM-ALL-PROV;
IMEISV=4565676567576576;
CW=CW-ALL-PROV;
CF=CFU-ALL-PROV-NONE-YES-NO-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFB-ALL-PROV-NONE-YES-YES-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFNRY-ALL-PROV-NONE-YES-YES-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFNRC-ALL-PROV-NONE-YES-NO-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFU-TS10-ACT-914369223311-YES-YES-25-YES-65535-YES-YES-NO-NO-NO-YES-YES-
YES-YES-NO;
ODBIC=BAIC;
ODBOC=BAOC;
ODBROAM=ODBOHC;
ODBPRC=ENTER;
ODBPRC=INFO;
ODBPLMN=NONE;
ODBPOS=NOBPOS-BOTH;
ODBECT=OdbAllECT;
ODBDECT=YES;
ODBMECT=YES;
ODBPREMSMS=YES;
ODBADULTSMS=YES;
<SUBEND
<SUBBEGIN
IMSI=11111111111133;
MSISDN=431234567899;
CB=BAOC-ALL-PROV;
CB=BOIC-ALL-PROV;
CB=BOICEXHC-ALL-PROV;
CB=BICROAM-ALL-PROV;
CW=CW-ALL-PROV;
CF=CFU-ALL-PROV-NONE-YES-NO-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO+-NO-NO;
CF=CFB-ALL-PROV-NONE-YES-YES-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFNRY-ALL-PROV-NONE-YES-YES-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFNRC-ALL-PROV-NONE-YES-NO-NONE-YES-65535-NO-NO-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFU-TS10-ACT-914369223311-YES-NO-NONE-YES-65535-YES-YES-NO-NO-NO-NO-NO-NO-NO-NO;
CF=CFD-TS10-REG-91430000000-YES-YES-25-YES-65535-YES-YES-NO-NO-NO-YES-YES-YES-YES-NO;
ODBIC=BICCROSSDOMESTIC;
ODBOC=BAOC;
ODBROAM=ODBOH;
ODBPRC=INFO;
ODBPLMN=PLMN1
ODBPLMN=PLMN3;
ODBPOS=NOBPOS-BOTH;
ODBECT=OdbAllECT;
ODBDECT=YES;
ODBMECT=YES;
ODBPREMSMS=NO;
ODBADULTSMS=YES;
<SUBEND
From what I understand, you are simply reading a text file and processing it and maybe replacing some words. You do not therefore need a data structure to store the words in. Instead you can simply read the file line by line and pass it through a bunch of if statements (maybe a couple booleans to check if the specific parameters you are searching for have been found?) and then rewrite the line you want to a new file.
Dealing with big files to implement data in machine learning algorithms, I did it by passing all of the file contents in a variable, and then using the String.split("delimeter") method (Supported from Java 8 and later), I broke the contents in a one-dimensional array, where each cell had the info before the delimeter.
Firstly read the file via a scanner or your way of doing it (let content be the variable with your info), and then break it with
content.split("<SUBEND");

Taking input in Java

I have some confusion if someone can help. Tried searching the web for it but didn't get any satisfying answer.
Why don't we simply use System.in.somemethod() to take input in Java just like we do for output? Like System.out.println() is used so why not System.in as it is? Why is there a long process for Input?
The only methods that System.in, an InputStream, provides are the overloads of read. Sure, you could do something like:
byte[] bytes = new byte[5];
System.in.read(bytes);
System.out.println(Arrays.toString(bytes));
to read five bytes from the console. But this has the following disadvantages:
You need to handle the checked IOException. (not shown in the code snippet above)
Hard to work with bytes. (unless you want them specifically)
You usually just want to read the input until the end of a line. With this it's hard to know where the end of a line is.
So that's why people use Scanners to wrap the System.in stream into something more user-friendly.
Taking input from the command line will always be trickier than just outputting data. This is because there is no way to know that the input is semantically correct, structured correctly or even syntactically correct.
If you just want to read bytes from System.in then a lot of the uncertainty of the input disappears. In that case there is only two things to take into account: I/O errors and end-of-input - both of which are also present for System.out. The only other thing that may be tricky is that InputStream may not return all the bytes that are requested in a single call to read.
So reading data from System.in isn't hard; interpreting the data - which often comes down to parsing the data or validating the data - is the hard part. And that's why often the Scanner class is used to make sense of the input.
Just as you cannot use System.out.somemethod() instead of System.out.println() in the same way you cannot use System.in.somemethod() instead of System.in.read().

Java Input Mismatch Exception with a specialized txt file

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

What is C++ equivalent of Java StdIn.isEmpty()

I am trying to learn something basing on Java resource, and I want to adapt it to C++.
Source of Java has:
while( !StdIn.isEmpty())
{
//Take input from standard input, and process it...
}
In C++ the closest solution I could come up with was
while( cin >> someString)
{
//process someString...
}
However, the problem is, that cin returns state of object. There is no way I can put wrong input into std::string. This could have worked for ints, but not for string. Any equivalent function, or workarounds?
Thanks in advance.
With C++ iostreams, and also with C's stdio, you cannot tell whether a file (such as std::cin/stdin) will be empty if you were to try reading from it. The only way to find out is to actually read from the file, and then check whether the attempt succeeded.
(Yes, you could use some form of peek, but that's nowhere near as idiomatic or practical.)
So a standard method in C++ might look like this, processing entire lines of input at a time:
for (std::string line; std::getline(std::cin, line); )
{
// process "line"
}
The loop body will only execute if you succeeded at extracting one line from the input. Once the input runs out of data, the loop condition is no longer satisfied (i.e. the stream is no longer "good"), and the loop stops.
The same idea applies to C's fgets, as well as to unformatted std::istream::read() and fread, and to platform-specific functions like Posix's read(2): You always attempt to obtain input, then check whether you got any input, and only if you did do you proceed to consume the input.

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