Issues with While loop condition - java

I am writing a program that reads a text file which contains match results, and then should output them in a table. I have a While loop within a While loop:
Scanner fileread1 = new Scanner(new File("demo.txt"));
int x = 0;
int y = 22;
int i = 0;
while (x <= y) {
while (fileread1.hasNext()) {
fileinput = fileread1.nextLine(); // this reads the next line of
// from the file
String line = fileinput;
String[] split = line.split(":");
boolean result = false;
int homescore1 = 0;
int awayscore1 = 0;
int goalsscored = 0;
boolean att = false;
boolean htt = false;
int atscore = 0;
int htscore = 0;
// When the text line is read, it is then split into four sections.
if (split.length == 4) {
// String text = line.trim();
String userteam = userteaminput;
String hometeam = split[0].trim();
String awayteam = split[1].trim();
String home_score = split[2].trim();
String away_score = split[3].trim();
// this is a test to try convert the goals string into a
// integer. If this fails, the result is not
// not valid and does not get outputted to the console.
try {
homescore1 = Integer.parseInt(home_score);
awayscore1 = Integer.parseInt(away_score);
result = true;
}
catch (NumberFormatException exception) {
// if the try is not able to convert, this will run
errors++;
}
if (userteam.equals(Teams.get(i))) {
if (awayteam.equalsIgnoreCase(userteam)) {
att = true;
games++;
goalsfor = goalsfor + awayscore1;
goalsagainst = goalsagainst + homescore1;
}
if (att == true && awayscore1 > homescore1) {
atwc++;
gameswon++;
}
else if (att == true && awayscore1 < homescore1) {
htwc++;
gameslost++;
}
else if (att == true && awayscore1 == homescore1) {
gamesdrawn++;
}
if (hometeam.equalsIgnoreCase(userteam)) {
htt = true;
totaluser++;
games++;
goalsfor = goalsfor + homescore1;
goalsagainst = goalsagainst + awayscore1;
}
if (htt == true && homescore1 > awayscore1) {
atwc++;
gameswon++;
}
else if (htt == true && homescore1 < awayscore1) {
htwc++;
gameslost++;
}
else if (htt == true && awayscore1 == homescore1) {
gamesdrawn++;
}
}
}
else {
errors++;
}
}
// ********************************************************************
// Leeds IF Statement
// ********************************************************************
if (Rhinos.equals(Teams.get(i)) {
Rhinos.goalsfor = Rhinos.goalsfor + goalsfor;
Rhinos.gameswon = Rhinos.gameswon + gameswon;
Rhinos.gameslost = Rhinos.gameslost + gameslost;
Rhinos.goalsagainst = Rhinos.goalsagainst;
Rhinos.gamesplayed = Rhinos.gamesplayed + games;
}
else if (Bulls.equals(Teams.get(i)) {
Bulls.goalsfor = Bulls.goalsfor + goalsfor;
Bulls.gameswon = Bulls.gameswon + gameswon;
Bulls.gameslost = Bulls.gameslost + gameslost;
Bulls.goalsagainst = Bulls.goalsagainst;
Bulls.gamesplayed = Bulls.gamesplayed + games;
}
x++;
i++;
goalsfor = 0;
gameswon = 0;
gameslost = 0;
gamesagainst = 0;
}
I know that there are only ever going to be 22 teams that have results in the text file supplied, so the first loop should run for 22 times.
The inner loop, will continue whilst the file provided has a next line. The text file may sometimes have more lines of results then other files. Within this loop, I have a reference to an Array item:
if (userteam.equals(Teams.get(i)))
In the first run, this will refer to 0 in my Array which, for the record, is Leeds Rhinos. Once the inner loop has completed, it then moves onto the outer loop - this deals with the results just recorded. If the current team is Leeds Rhinos, it should then add the values. The i should then have 1 added, so for the next loop, it refers to the index of 1 of the array, not 0. (I have more IF statements here, all identical but refer to other teams) Variables get set back to 0, ready for the next run.
The issue I have, is that i does not seem to have 1 added each time it runs through, so I am only getting results passed through for one team. If I manually specify which array index to look (say 3) it will run through, and the team will have their results successfully recorded.
Is there a way I can get 1 added to i every time it loops? I'm not sure if this is the correct java loop to use, but to me, seemed the most logical. There are some objects not declared here - this is just a snippet of the code, left out the declarations as I know they work, and there's a lot declared.

If you're worried about failed incrementation, it would be better to use a For loop.
Instead of having a while (x < y) and sticking an increment statement somewhere in your code,
a
for (i = 0; i < y; i++) { // do tests here }
loop will guarantee that you always increment and run the test for the next team.
For future reference, when using while loops and incrementing, the incrementation is almost always done at the END of the while loop, and not somewhere in between. The incrementation statement should also almost never be in a conditional statement (which might cause an infinite loop).

Your question is not clear. But let's point out something in the code you provided
1) What is the difference between your if and else if statement? They are checking exact same thing
if (userteam.equals(Teams.get(i)) {
Rhinos.goalsfor = Rhinos.goalsfor + goalsfor;
Rhinos.gameswon = Rhinos.gameswon + gameswon;
Rhinos.gameslost = Rhinos.gameslost + gameslost;
Rhinos.goalsagainst = Rhinos.goalsagainst;
Rhinos.gamesplayed = Rhinos.gamesplayed + games;
}
else if (userteam.equals(Teams.get(i)) {
Bulls.goalsfor = Bulls.goalsfor + goalsfor;
Bulls.gameswon = Bulls.gameswon + gameswon;
Bulls.gameslost = Bulls.gameslost + gameslost;
Bulls.goalsagainst = Bulls.goalsagainst;
Bulls.gamesplayed = Bulls.gamesplayed + games;
}
2) What are you doing with variable x, I don't see anywhere you are increasing it.
3) On very first run, when x<=y, the inner loop will finish reading all lines, so even if you increase the X some point, from second run the inner loop will not execute. As it already finished reading all lines. So no point doing this
Again if you provide some more inside on what you want to accomplish, may be with the sample text file data, that would probably help answering your question.
Thank you.

Your formatting is working against you here; properly indented, your code structure is something like this (note, I had to add in missing closing braces, }, at the end of the code you provided as I assume you just missed them when you copied your code over):
Scanner fileread1 = new Scanner(new File("demo.txt"));
int x = 0;
int y = 22;
int i = 0;
while (x <= y) {
while (fileread1.hasNext()) {
fileinput = fileread1.nextLine(); // this reads the next line of
/* stuff */
if (split.length == 4) {
/* stuff */
x++;
i++;
}
}
}
Your incrementation of x and i is nested within if (split.length == 4) {, meaning that x and i will only be incremented in that specific case and not at the end of each iteration of the inner while loop.

Related

The exception message is printed in an infinite loop

I've been writing code that manually prints json (without the json library) after reading a CSV. It's to understand the structure for a project of this scale, which involves IO and Exception handling.
So, I've been debugging this snippet of code since yesterday. I've identified the problem, but have not been able to solve it.
I currently have an infinite loop after the exception message is printed. For context, in the part of the code that is missing, the user inputs the number of files and it creates an array of files. The snippet of code inside my message is a method which verifies if a csv has a an empty field. Count is there to count the line numbers, if count == 1 and there is an empty field, it will throw CSVFileInvalidException, which is a custom exception I made for this project. If count is bigger than 1, it throws CSVDataMissingException, i.e. another custom exception.
The timeline of the debugging goes as follows:
At first, when I had the infinite loop, I thought the regex caused my error, since I heard it could be badly implemented. I checked and each element is exactly what I want (a string, which represents a field in the csv). So, it wasn't regex since the behavior was normal.
Secondly, I realized I accidentally put my try block was inside my while loop, so I put it on the outside. No Luck. The issue still persisted.
Then, I figured out the issue. It read the line handled the exception and since there was no failsafe to exit the while loop, it did so non-stop. So, I added an exit condition for the while loop. So, I added
if ((count > 1) && (s.nextLine() == null || s.nextLine().equals(""))) {
break;
}
This checks if the line number is higher than 1 and if the nextLine is null or empty. I thought this had solved the infinite loop problem that I had. Once I implemented this, nothind after the regex ended up being outputted. I checked with multiple println().
I then realized I made a typo in one of the for loops. Now, I'm back to the same behavior it exhibited earlier. It's redoing the same sequence inside the while loop again. In this case, it's looping the message from CSVFileInvalidException, so i.e. "The file called : " + f[i] + " is invalid. A field is missing. The file is not converted to JSON."
So, I'm assuming there's something that doesn't make sense logically. I've tried multiple solutions and the exceptions are now never reached.
Sorry for the long code, the element that is being repeated is at the bottom, and everything else is inside the while loop, so I'm not sure if it's something I implemented there.
for (int i = 0; i < f.length; i++) {
int count = 1;
try {
while (s.hasNextLine()) {
lines = s.nextLine();
if ((count > 1) && (s.nextLine() == null || s.nextLine().equals(""))) {
break;
}
//isolate the commas, and remove the quotes and extra space, so that the text remains clean and similar
String[] line_parts = lines.replaceAll("^\"", "").split("\"?(,|$)(?=(([^\"]*\"){2})*[^\"]*$) *\"?", -1);
Cloned_Elements[] cloned_elements_array = new Cloned_Elements[line_parts.length];
for (int z = 0; z < cloned_elements_array.length; z++) {
String[] array_ofstring = new String[line_parts.length];
for (int x = 0; x < array_ofstring.length; x++) {
array_ofstring[x] = "lol";
}
cloned_elements_array[z] = new Cloned_Elements(array_ofstring);
}
for (int j = 0; j < line_parts.length - 1; j++) {
if (count == 1) {
if (line_parts[j].equals("") || line_parts[j] == null) {
ce.setCloned_array(line_parts);
throw new CSVFileInvalidException("The file called : " + f[i] + " is invalid. A field is missing. The file is not converted to JSON.");
} else {
if (j < line_parts.length) {
String[] length_1 = cloned_elements_array[j].getCloned_array();
cloned_elements_array[j].setCloned_array(line_parts);
}
}
} else {
if (line_parts[j].equals("") || line_parts[j] == null) {
ce.setCloned_array(line_parts);
throw new CSVDataMissingException("In file " + f[i] + ", there is missing data in line #" + (count) + ". Thus, the file is not converted to JSON.");
} else {
if (j < line_parts.length) {
cloned_elements_array[j].setCloned_array(line_parts);
}
}
}
}
count++;
}
} catch (CSVDataMissingException e2) {
System.err.println(e2.getMessage());
try {
p = new PrintWriter(new FileOutputStream(js[js.length - 1], true));
int line_nb = count+1;
String[] error_array = ce.resize_string_arr();
for (int x = 0; x < error_array.length; x++) {
if (error_array[x].equals("") || error_array[x] == null) {
error_array[x] = "xxx";
}
}
p.println("In file " + f[i] + " ,line " +line_nb + " is missing an element.");
for (int z = 0; z < error_array.length; z++) {
p.print(error_array[z] + " ");
}
p.println();
p.println();
break;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} catch (CSVFileInvalidException e1) {
System.err.println(e1.getMessage());
try {
p = new PrintWriter(new FileOutputStream(js[js.length - 1], true));
p.println("File " + f[i] + " is invalid.");
String[] error_array = ce.resize_string_arr();
for (int x = 0; x < error_array.length; x++) {
if (error_array[x].equals("") || error_array[x] == null) {
error_array[x] = "xxx";
}
}
p.println("Field is missing : " + error_array.length + " detected, 1 is missing.");
for (int z = 0; z < error_array.length; z++) {
p.print(error_array[z] + " ");
}
p.println();
p.println();
break;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}

Is there a way to make it output the values of result in my code?

I'm working on my university assignment which requires me to program an eviction algorithm. I am new to programming and have only done Python before. Below is what I have done so far. The code compiles fine but I am not getting the output that I was expected to get.
getting user input and then calling the method for no eviction:
System.out.println();
System.out.println("Cache content: ");
print_array(org_cache, size);
System.out.println("Request sequence: ");
print_array(request, count);
try {
copy_array(org_cache, cache, size);
System.out.println("no_evict");
no_evict(cache, size, request, count);
}
catch (Exception e) {
System.out.println("ERROR: no_evict");
the method:
static void no_evict(int[] cache, int c_size, int[] request, int r_size) {
int i = 0;
boolean found = false;
String result = "";
String resultHit = "";
String resultMiss = "";
for(int x = 0; x < r_size; x++) { //for loop goes through every requests
while(i < c_size || found == false) { //while loop brings a page through every cache value
if(request[x] == cache[i]){
found = true;
} else {
i += 1;
}
}
if(found == true) {
result += "h";
resultHit += "h";
} else {
result += "m";
resultMiss += "m";
x += 1; //proceeds to next value in request sequence
}
}
System.out.println(result);
System.out.println(resultHit.length() + "h " + resultMiss.length() + "m");
}
it does not output the result string but instead outputs this:
Cache content:
20 30 10 5 40
Request sequence:
20 30 10
no_evict
You will notice that your program doesn't actually exit. This is because it's stuck in an infinite loop, just as what would happen in Python.
If you run it in a debugger or hit Ctrl-\ in a console, you'll see that it's stuck in this loop:
while(i < c_size || found == false) { //while loop brings a page through every cache value
if(request[x] == cache[i]){
found = true;
} else {
i += 1;
}
}
The condition is true as long as i < c_size because you used ||, logical "or". You probably intended to use &&, so that find = true will break the loop.
PS: The Java compiler doesn't care about indenting, but humans do. Please use your editor's indenting function to make the code easier to read.
As #that other guy mentioned, you are using || instead of &&.
But you don't need the second qualifier. Just use:
i = 0;
while(i < c_size ) {
if(request[x] == cache[i]){
found = true;
break;
} else {
i += 1;
}
}
or
for ( int i=0; i < c_size; i++ ) {
if ( request[x] < cache[i] ) {
found = true;
break;
}
}
There is another problem with your algorithm: you initialise i right at the beginning but never reset it to zero.
You probably want to move the int i = 0 statement between the for and the while statement.

Java - TIMEOUT (Infinite loop) error

One of the practice problems our instructor gave us for an intro to JAVA class is giving me an error for creating an infinite loop. I would like to know how to get the same output that I am getting (test output is shown in the screenshot) without this error.
The instructions on the assignment are as follows:
Write a method named flipLines that accepts as its parameter a Scanner for an input file and that writes to the console the same file's contents with successive pairs of lines reversed in order. The program should print the first pair of lines in reverse order, then the second pair in reverse order, then the third pair in reverse order, and so on. An input file can have an odd number of lines in which case the last line is printed in its original position.
This image is a screenshot of the error along with my code on the website.
This is my first post so hopefully I formatted this correctly.
Just in case, here's my code again:
public static void flipLines(Scanner input)
{
int x = 0;
String evenLine = "";
String oddLine = "";
boolean value = true;
while (value = true)
{
if (input.hasNextLine())
{
x++;
}
else
{
value = false;
}
}
for (int i = 0; i < x; i++)
{
if (i < x && i % 2 == 0)
{
evenLine = input.nextLine();
System.out.println(evenLine);
}
else
{
continue;
}
}
for (int j = 0; j < x; j++)
{
if (j < x && j % 2 != 0)
{
oddLine = input.nextLine();
System.out.println(oddLine);
}
else
{
continue;
}
}
}
change your assignment
while (value = true)
to comparison
while (value == true)
value = true assigns true to value and returns true, which means the loop will never end.
EDIT :
In addition, input.hasNextLine() will always return true since you are not reading any line until after the while loop, which is why that loop never ends.
You can't find the number of input lines without actually reading the lines.
Your for loops also don't do what you think they should do. Just because you skip an iteration of the for loop doesn't mean that you skip a row of the input.
What you need is a single loop that reads two lines (assuming there are two lines available) in each iteration and prints them in reversed order.
String line1 = null;
while (input.hasNextLine()) {
line1 = input.nextLine();
if (input.hasNextLine()) {
String line2 = input.nextLine();
System.out.println(line2);
System.out.println(line1);
line1 = null;
}
}
if (line1 != null)
System.out.println(line1);

if statement constantly printing

My if statement is acting weird, instead of printing only when wrong is greater than 6, it is constantly printing "dead" every time. Any ideas on why that is? I've updated the code so you can better understand my logic.
int j = 0;
String line = "";
for(j = 0; j<64; j++) {
wordLength[j] = wordList[j].length();//gets length of words in wordList
}//end for
int f = 2;//change num to change level
int m = 0;
//creates line first then put into .setText
while(m<wordLength[f]) {
line += "__ ";
m++;
}//end for
jlLines.setText(line);
tf.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {//when enter key pressed
JTextField tf = (JTextField)e.getSource();
letter = tf.getText();
jlLetsUsed.setText(jlLetsUsed.getText() + letter + " ");//sets jlabel text to users entered letter
char[] jlabelText = jlLines.getText().toCharArray();//converts string to character array (array length is length of string)
char userEnteredChar = letter.charAt(0);
int wrong = 0;
int level = 2;//change num to change level
int i = 0;
for(i = 0; i<wordList[level].length(); i++){
if(wordList[level].charAt(i) == userEnteredChar){
jlabelText[3 * i] = ' ';
jlabelText[3 * i + 1] = userEnteredChar;
jlLines.setText(String.valueOf(jlabelText));
}else{
wrong++;
System.out.println(wrong);
}if(wrong >= 6){
System.out.println("dead");
break;
}
}//end for
}//end actionPerformed method
Evidently wrong is always >= 6. One possibility is that level is longer than 1 character and thus the contains check is always false. That's if it's always 'wrong' even with a 'right' guess.
The more likely possibility is that because the check where you increment wrong is inside the loop, any time wordList[level] is 6 or more characters in length and does not contain letter, wrong will be incremented 6 or more times.
You probably should put the check outside the loop.
for(int i = 0; i<wordList[level].length(); i++){
if(wordList[level].charAt(i) == userEnteredChar){
jlabelText[3 * i] = ' ';
jlabelText[3 * i + 1] = userEnteredChar;
jlLines.setText(String.valueOf(jlabelText));
}
}
if(!wordList[level].contains(letter)){
wrong++;
}
if(wrong>=6){
System.out.println("dead");
}
By the way, an obvious suggestion here is that if you are checking contains, you might as well check it first and skip the 'revealing' loop somehow if contains is false.
It looks like wrong should probably be a field somewhere. Shown here I've declared it as a field on the ActionListener. Don't put it on the ActionListener, put it somewhere else, preferably on the containing class. I don't see where else to put it though and this may work initially. The point is to keep track of 'wrong' guesses outside the single guess in actionPerformed. That means you have to declare it somewhere outside the method scope.
tf.addActionListener(new ActionListener() {
int wrong;
#Override
public void actionPerformed(ActionEvent e) {
JTextField tf = (JTextField)e.getSource();
char userEntry = tf.getText().charAt(0);
jlLetsUsed.setText(jlLetsUsed.getText() + userEntry + " ");
int level = 2;
if (!wordList[level].contains(String.valueOf(userEntry))) {
wrong++;
if (wrong >= 6) {
System.out.println("dead");
}
return;
}
char[] jlabelText = jlLines.getText().toCharArray();
for (int i = 0; i < wordList[level].length(); i++) {
if (wordList[level].charAt(i) == userEntry) {
jlabelText[3 * i] = ' ';
jlabelText[3 * i + 1] = userEntry;
}
}
jlLines.setText(String.valueOf(jlabelText));
}
});

List collections interface in java

Please find below a function in my code:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id,
List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
int yes = 0;
mListPosChanged = mListPos;
//--------------------------------------------------------------------------
for (int crfLinesMainIter = begin; crfLinesMainIter < end; ) {
System.out.println(crfLines.get(crfLinesMainIter));
//---------------------------------------------------------------------------
//the total number of attributes without orthographic features
//in a crfLine excluding the class attribute is 98
if (!crfLines.get(crfLinesMainIter).equals("") && crfLines.get(crfLinesMainIter).split("\\s").length == 98) {
//in mList parenthesis are represented by the symbol
//in crfLines parenthesis are represented by -LRB- or -RRB-
//we make a check to ensure the equality is preserved
if(val.equals(crfLines.get(crfLinesMainIter).split("\\s")[0])) {
yes = checkForConsecutivePresence(crfLinesMainIter, mList, mListPos, id, crfLines);
if (yes > 0) {
mListPosChanged += yes;
System.out.println("formCrfLinesWithMentionClass: "+mListPosChanged);
for (int crfLinesMentionIter = crfLinesMainIter;
crfLinesMentionIter < crfLinesMainIter + yes;
crfLinesMentionIter++) {
String valString = "";
if (crfLinesMentionIter == crfLinesMainIter) {
valString += crfLines.get(crfLinesMentionIter);
valString += " B";
crfLines.add(crfLinesMentionIter, valString);
}
else {
valString += crfLines.get(crfLinesMentionIter);
valString += " I";
crfLines.add(crfLinesMentionIter, valString);
}
}
crfLinesMainIter += yes;
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
else {
++crfLinesMainIter;
}
}
return crfLines;
}
The problem I face is as follows:
crfLines is a List collections interface.
When the for loop (between //-----) starts out, the crfLines.get(crfLinesMainIter) works fine. But once, it enters into the if and other processing is carried out on it, even though "crfLinesMainIter" changes the crfLines.get(crfLinesMainIter) seems to get a certain previous value. It does not retrieve the actual value at the index. Has anyone faced such a scenario? Would anyone be able to tell me why this occurs?
My actual question is, when does it occur that even though the indexes might be different a list.get() function still retrieves a value from before which was at another index?
For example:
List crfLines = new LinkedList<>();
if crfLinesMainIter = 2
crfLines.get(crfLinesMainIter) brings me a value say 20 and this value 20 satisfies the if loop condition. So then further processing happens. Now when the for loop executes the values of crfLinesMainIter changes to say 5. In this case, crfLines.get(5) should actually bring me a different value, but it still brings me the previous value 20.
(Not an answer.)
Reworked (more or less) for some modicum of readability:
private static List<String> formCrfLinesWithMentionClass(int begin, int end, String id, List<String> mList, int mListPos, List<String> crf) {
List<String> crfLines = crf;
mListPosChanged = mListPos;
int i = begin;
while (i < end) {
if (crfLines.get(i).equals("") || (crfLines.get(i).split("\\s").length != 98)) {
++i;
continue;
}
if (!val.equals(crfLines.get(i).split("\\s")[0])) {
++i;
continue;
}
int yes = checkForConsecutivePresence(i, mList, mListPos, id, crfLines);
if (yes <= 0) {
++i;
continue;
}
mListPosChanged += yes;
for (int j = i; j < i + yes; j++) {
String valString = crfLines.get(j);
valString += (j == i) ? " B" : " I";
crfLines.add(j, valString);
}
i += yes;
}
return crfLines;
}
What is mListPostChanged? I find it confusing that it's being set to the value of a parameter named mListPos--it makes me think the m prefix is meaningless.
What is val in the line containing the split?

Categories