Java NoSuchElementException using String Tokenizer - java

I'm reading in a transaction file that looks like this:
1112, D
4444, A, Smith, Jones, 45000, 2, Shipping
6666, U, Jones
8900, A, Hill, Bill, 65000, 0, Accounting
When I attempt to read the file line by line using ", " the token, the program bombs out with a NoSuchElementException error at the first record. I've deduced that the condition in which I'm reading the file is causing the issue, particularly at the while loop below. I've tried using an "if" statement and setting the conditions to "while (st2.hasMoreTokens)" and a combination of the two but the error persists and I'm not sure why? Thank you in advance for any assistance. This is the code below:
Scanner transactionFile = new Scanner (new File(fileName2));
for (int i = 0; i < T_SIZE; i++) {
line2[i] = transactionFile.nextLine();
transaction[i] = new Transaction();
st2 = new StringTokenizer(line2[i], ", ");
transaction[i].setEmployeeID(Integer.parseInt(st2.nextToken()));
transaction[i].setAction(st2.nextToken());
while ((transaction[i].getAction() != "D")) {
transaction[i].setLastName(st2.nextToken());
transaction[i].setFirstName(st2.nextToken());
transaction[i].setSalary(Integer.parseInt(st2.nextToken()));
transaction[i].setNumOfDependants(Integer.parseInt(st2.nextToken()));
transaction[i].setDepartment(st2.nextToken());
}
}

Take a look at the your while loop. The == operator in Java checks if two objects are the same reference, which is rarely a good idea to rely on, and probably causes this loop to loop infinately (or at least until the program crashes with an exception). What you'd want to do, logically, is check that both strings are equal, i.e., both contain the string "D":
while (!transaction[i].getAction().equals("D"))

str.nextToken()
function access an element when it is called and increments index of it so your are calling it more then the elements in array so it cant have the access to the higher indexes and throws an exception of noSuchElementFound

Related

Output for reversing a string does not come as expected

Chandu is a bad student. Once his teacher asked him to print the reverse of a given string. He took three hours to solve it. The teacher got agitated at Chandu and asked you the same question. Can you solve it?
Input
The first line contains an integer T, denoting the number of test cases.
Each test case contains a string S, comprising of only lower case letters.
Output
For each test case, print the reverse of the string S.
Constraints
1 <= T <= 10
1 <= |S| <= 30
Input Sample Output(Plaintext Link)
2
ab ba
aba aba
Time Limit
1 sec(s) for each input file.
Memory Limit
256 MB
Source Limit
1024 KB
MyApproach1
MyApproach2
To reverse a string I used XOR logic to reverse the string.
#Edit
public static void main(String args[] ) throws Exception
{
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for (int i = 1; i <= T; ++i)
{
String input = sc.next();
int len = input.length();
StringBuilder input1 = new StringBuilder(len);
int end = input.length()-1;
int start = 0;
while (start<end)
{
input1.setCharAt(start,input.charAt(start)^input.charAt(end));
input1.setCharAt(end,input.charAt(end)^input.charAt(start));
input1.setCharAt(start,input.charAt(start)^input.charAt(end));
++start;
--end;
}
System.out.println(input1.toString());
}
}
I am still getting the following error.
How do I correct this?
For approach 1, all you need to do is remove the call to sc.nextLine() and everything will be fine. That's because each line contains a "token" i.e. a word, delimited by whitespace. That's what sc.next() will return. No need to call nextLine() after that.
For your approach 2, you should carefully read the API documentation of StringBuilder. This shows you how to create a String from a StringBuilder, and vice versa. (Whenever I write Java code, I have a browser window with the API documentation for quick reference next to my editor window. It's very useful.)
Edit (after the latest edit to the question):
There is a compilation problem and a runtime problem. First, the XOR operator produces a result of type int, even if its operands are char. So you should put your expression in parentheses and cast it to char. Once you've done that, you'll get a runtime error because you are trying to index an element of a StringBuilder which does not yet exist. When you created the StringBuilder like this:
StringBuilder input1=new StringBuilder(len);
len is the initial capacity. The value of the StringBuilder instance is initially "". You then call setCharAt() but the current size of the StringBuilder is 0, so you get an index-out-of-bounds exception. You need to initialise the StringBuilder with the string itself:
StringBuilder input1=new StringBuilder(input);
Now you won't get an exception, but you'll get the wrong answer. That's because of a problem with your XOR logic.
After
sc.nextInt();
write
sc.nextLine();
before starting first loop.
For the two lines of your code
String s1 = sc.next();
sc.nextLine();
write just
String s1 = sc.nextLine();
The next() function gives you characters before a space while next line gives you whole line.
It'll work Fine.

How do I check see a newline character with my scanner if I'm using a delimiter?

I'm trying to make an undirected graph with some of the nodes (not all, unlike my example) being connected to one another. So my input format will look like
3
1:2,3
2:1,3
3:1,2
Meaning there's three nodes in all, and 1 is connected to 2 and 3, 2 is connected to 1 and 3 and so on.
However, I cannot understand how to take the input in a meaningful way. Here's what I've got so far.
public Graph createGraph() {
Scanner scan = new Scanner(System.in).useDelimiter("[:|,|\\n]");
int graphSize = scan.nextInt();
System.out.println(graphSize);
for (int i = 0; i < graphSize; i++) {
while (!scan.hasNext("\\n")) {
System.out.println("Scanned: " + scan.nextInt());
}
}
return new Graph(graphSize);
}
Can my
while (!scan.hasNext("\\n"))
see the newline character when I'm using a delimiter on it?
In my opinion, you shouldn't be using those delimiters if they are meaningful tokens. In the second line for example, the first integer doesn't have the same meaning as the others, so the : is meaningful and should be scanned, even if only to be discarded later. , however doesn't change the meaning of the tokens that are separated by it, so it's safe to use as a delimiter : you can grab integers as long as they are delimited by ,, they still have the same meaning.
So in conclusion, I would use , as a delimiter and check manually for \nand : so I can adapt my code behaviour when I encounter them.
yup, scanner can definitely detect new line. infact you dont even have to explicitly specify it. just use
scan.hasNextLine()
which essentially keeps going as long as there are lines in your input
Edit
Why dont you read everything first and then use your for loop?
Alright I figured it out. It's not the prettiest code I've ever written, but it gets the job done.
public Graph createGraph() {
Scanner scan = new Scanner(System.in);
number = scan.nextLine();
graphSize = Integer.valueOf(number);
System.out.println(graphSize);
for (int i = 0; i < graphSize; i++) {
number = scan.nextLine();
Scanner reader = new Scanner(number).useDelimiter(",|:");
while (reader.hasNextByte()) {
System.out.println("Scanned: " + reader.nextInt());
}
}
return new Graph(graphSize);
}

Read words until user writes 'end', then, order lexicographically(as in a dictionary), show the last word

User will enter words until the last word written is "end", then the code has to order lexicographically, as we have in a dictionary, all the words entered before 'end' and print the last word, the one classified the last.
//.....
Scanner word = new Scanner (System.in);
String keyword="end";
String finalstring;
String[] firststring= new String[1000]; //Don't know how to stablish a //dynamic string[] length, letting the user stablish the string[].length
for(int c=0;c<firststring.length;c++){
firststring[c]=word.next();
if(firststring[c].equals(keyword)){
finalstring=firststring[c].substring(0,c);
c=cadena.length-1; //To jump out of the for.
}
}
for (int c=0;c<finalstring.length();c++) {
for(int i=c+1;i<finalstring.length();i++) {
if (firststring[c].compareTo(firststring[i])>0) {
String change = firststring[c];
firststring[c] = firststring[i];
firststring[i] = change;
}
}
}
System.out.print("\nYou entered "end" and the last word classified is "+finalstring[finalstring.length()-1]); //Of course, error here, just did it to put one System.out.print of how should the result be.
}
}
This is what I tried, though, without any type of success, any help of yours will be a big help, thank you ALL!
Don't know how to stablish a dynamic string[] length, letting the user establish the string[].length
It is not necessary to do that. But here's how.
Approach #1: ask the user to give you a number and then allocate the array like this:
String[] strings = new String[theNumber];
Warning: the requirements don't say you are allowed to do that, and you may lose marks for deviating from the requirements.
Approach #2: use an ArrayList to accumulate a list of words, the use List.toArray to create an array from the list contents. (Read the javadocs for list to work it out.)
Of course, error here, just did it to put one System.out.print of how should the result be.
Yea. One problem is that the length is 1000, but you don't have 1000 actual strings in the array. The same problem affects your earlier code too. Think about is ...
I'm not going to fix your code to make it work. I've given you enough hints for you to do that for yourself. If you are prepared to put in the effort.
One more hint: you can / should use break to break out of the first loop.
I know some words are not in English but in Catalan, but the code can be perfectly understood, yesterday I finally programmed this answer:
public static void main(String[] args) {
Scanner entrada= new Scanner(System.in);
System.out.println("Escriu les paraules que vulguis, per acabar, usa la paraula 'fi'.");
String paraules = "";
int c=0;
do {
String paraula = entrada.next();
if (paraula.equals("fi")) {
c++;
} else {
if (paraula.compareTo(paraules) > 0) {
paraules = paraula;
}
}
} while (c==0);
System.out.println("L'última parala ordenada alfabèticament és "+paraules+".\n");
}
}

Stanford Tokenizer NullPointerException

I was just struck with an odd exception from the entrails of StanfordNLP, when trying to tokenize:
java.lang.NullPointerException at
edu.stanford.nlp.process.PTBLexer.zzRefill(PTBLexer.java:24511) at
edu.stanford.nlp.process.PTBLexer.next(PTBLexer.java:24718) at
edu.stanford.nlp.process.PTBTokenizer.getNext(PTBTokenizer.java:276)
at
edu.stanford.nlp.process.PTBTokenizer.getNext(PTBTokenizer.java:163)
at
edu.stanford.nlp.process.AbstractTokenizer.hasNext(AbstractTokenizer.java:55)
at
edu.stanford.nlp.process.DocumentPreprocessor$PlainTextIterator.primeNext(DocumentPreprocessor.java:270)
at
edu.stanford.nlp.process.DocumentPreprocessor$PlainTextIterator.hasNext(DocumentPreprocessor.java:334)
The code that cause it looks like this:
DocumentPreprocessor dp = new DocumentPreprocessor(new StringReader(
tweet));
// unigrams
for (List<HasWord> sentence : dp) {
for (HasWord word : sentence) {
// do stuff
}
}
// bigrams
for (List<HasWord> sentence : dp) { //<< exception is thrown here
Iterator<HasWord> it = sentence.iterator();
String st1 = it.next().word();
while (it.hasNext()) {
String st2 = it.next().word();
String bigram = st1 + " " + st2;
// do stuff
st1 = st2;
}
}
What is going on? Has this to do with me looping over the tokens twice?
This is certainly an ugly stacktrace, which can and should be improved. (I'm about to check in a fix for that.) But the reason that this doesn't work is that a DocumentProcessor acts like a Reader: It only lets you make a single pass through the sentences of a document. So after the first for-loop, the document is exhausted, and the underlying Reader has been closed. Hence the second for-loop fails, and here crashes out deep in the lexer. I'm going to change it so that it just will give you nothing. But to get what you want you either want to (most efficient) get both the unigrams and bigrams in one for-loop pass through the document or to create a second DocumentPreprocessor for the second pass.
I think it.next().word() is causing it.
Change your code so you can first check if it.hasNext() and then do it.next().word() .

strange problem in an array

I'm working on a little server app with Java. So, I'm getting informations from different client, and if information comes in, the following method is called:
public void writeToArray(String data) {
data = trim(data);
String[] netInput = new String[5];
netInput[0]="a";
netInput[1]="a";
netInput[2]="a";
netInput[3]="a";
netInput[4]="a";
netInput = split(data, ",");
pos_arr = PApplet.parseInt(netInput[0]);
rohr_value = PApplet.parseInt(netInput[1]); // THIS LINE KICKS OUT THE ERROR.
if(pos_arr >0 && pos_arr<100) {
fernrohre[pos_arr] = rohr_value;
println("pos arr length: " + fernrohre[pos_arr]);
println("pos arr: " + pos_arr);
}
The console on OS X gives me the following error:
Exception in thread "Animation Thread"
java.lang.ArrayIndexOutOfBoundsException:1
at server_app.writeToArray(server_app.java:108) at server_app.draw(server_app.java:97)
at processing.core.PApplet.handleDraw(PApplet.java:1606)
at processing.core.PApplet.run(PApplet.java:1503)
at java.lang.Thread.run(Thread.java:637)
As you can see, I tried to fill the array netInput with at least 5 entries, so there can't be an ArrayIndexOutOfBoundsException.
I don't understand that, and I'm thankful for your help!
It would work already for me, if I can catch the error and keep the app continuing.
You put 5 Strings into the array, but then undo all your good work with this line;
netInput = split(data, ",");
data obviously doesn't have any commas in it.
In this line
netInput = split(data, ",");
your array is being reinitialized. Your split method probably returns an array with only 1 element (I can guess that data string doesn't contain any ",").
Update
The split() method is custom, not String.split. It too needs to be checked to see what is going wrong. Thanks #Carlos for pointing it out.
Original Answer
Consider this line:
netInput = split(data, ",");
This will split the data string using comma as a separator. It will return an array of (number of commas + 1) resulting elements. If your string has no commas, you'll get a single element array.
Apparently your input string doesn't have any commas. This will result in a single element array (first element aka index = 0 will be the string itself). Consequently when you try to index the 2nd element (index = 1) it raises an exception.
You need some defensive code,
if(netInput.length > 1)
pos_arr = PApplet.parseInt(netInput[0]);
rohr_value = PApplet.parseInt(netInput[1]);
You make
netInput = split(data, ",");
and
split(data, ",");
returns one element array
You are re-assigning your netInput variable when the split() method is called.
The new value might not have an array count of 5.
Can you provide the source for the split() method?

Categories

Resources