Java- Scanner is not reading String properly - java

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.

Related

Finding end of file in Java

I have a method that loops through a file to find the number of lines.
static int findFileSize(Scanner f){
System.out.println("Got to counter:");
String str;
int line_count = 0;
while(f.hasNextLine()) {
line_count++;System.out.println(line_count);
//str = f.nextLine();
}System.out.println("File size: " + line_count);
return line_count;
}//end findFileSize
When i don't include the str = f.nextLine();, i can see it indexing indefinitely. What causes this to happen? And is there a way of finding the number of lines in a .txt file without needing to unnecessarily store a data into a string?
What causes this to happen?
You aren't reading anything from the Scanner, you're just asking it if you will be able to read something.
If you walk into a shop and ask if they have, say, carrots, if the answer is "yes", but you don't buy any carrots, the shop still has carrots. So, if you walk out and walk in to ask again, they will still have the carrots, so they will again answer "yes" (unless somebody else has bought them).
You have to "buy the carrots" by using f.nextLine().
without needing to unnecessarily store a data into a string?
You don't have to store it in a variable:
f.nextLine();
will read the String and immediately discard it. But there isn't really a huge difference between this and storing it in a variable: the variable only keeps the contents of the last-read line anyway. (But since you don't give str an initial value, it's not definitely assigned after the loop, so you can't read its value after the loop in any case).

Not sure why my for loop isn't working the way i intended it to

So, before I start I just wanted to say that I'm very new to Java as a language and I've been reading a text book that was recommended to me.
One of the examples provided within the text book on for loops had the following code, which is meant to generate an infinite for loop until the user presses the character 'S' on their keyboard.
Here is the code:
class ForTest {
public static void main(String args[])
throws java.io.IOException {
int i;
System.out.println("Press S to stop.");
for (i = 0; (char) System.in.read() != 'S'; i++)
System.out.println("Pass #" + i);
}
}
I copied the code exactly as it was written within the book but when I run the program, to my surprise, it doesn't start printing out numbers onto the console. Additionally, whenever I press any keys on the keyboard it generates three numbers within the sequence. Example shown below:
I have also included a screenshot of the code from the book below:
I was wondering whether anyone knows why this is the case!
Any help would be greatly appreciated thanks.
The reason it's printing multiple times is because multiple characters are detected.
In your case, it's printing twice because you entered a value (Pass 1) and a new line (Pass 2)
The problem you have is not with System.in.read(), but because the console is usually using a buffered approach. Meaning that data is only transferred to the System.in.read() once you press enter.
So to get the example working, you would have to switch the console to an unbuffered mode, but there is no portable way to do this, because there are so much different types of consoles. Maybe have a look at what editor/console the book is using
This block of code looks like it was written by someone who was deliberately trying to make it obtuse and difficult to comprehend for a beginner.
The middle expression of a for statement is the criterion for taking the next step of the loop. It is evaluated before each step of the loop to determine whether the for loop is complete yet. In this case, it calls in.read() and checks if the input is S before each step of the loop.
in.read() waits for the next line of input it gets. When you enter a value and press Enter, that line gets read, so the loop takes a step. And a new line is also entered, so the loop takes a second step.
It will not print lines to the console unless you enter lines, because in.read() causes the program to block (wait) for the next input.

Design Pattern in Java for Getting Input and Acting on it

I'm trying to make a tic-tac-toe game and I'm encountering a lot of copy-paste work for inputs. I'm trying to figure out what design pattern and implementation works for prompting the user, collecting their input, comparing it and then acting by assigning a value. Right now my code looks like this.
public void promptPlayerCount(BufferedReader in) throws IOException {
String input;
// initial prompt
System.out.println("How many players?");
input = "try again";
while (input.equals("try again")) {
input = in.readLine();
// extract data and check it
switch (Integer.parseInt(input)) {
case 1:
// assignment
playerCount = 1;
break;
case 2:
playerCount = 2;
break;
default:
input = "try again";
// clarified instructions
System.out.println("please enter 1 or 2");
}
}
}
There's a part of me that thinks I could make a function (maybe a factory?) that allows me to generate a function by passing the constructing function the details of the initial prompt, the extraction method, the assignment action and the clarification message.
Would this be best done with lambda functions?
Text input is hard, especially if you can't trust your user (like in a game). Your parseInt will throw a nasty exception right off if your value isn't an integer.
Also standard in is not friendly. I assume this is for an assignment so I won't fault you for using it, but in anything where you don't HAVE to use stdin, don't. The problem is that it's amazingly difficult to get Java to respond to anything less than an entire line with an enter at the end.
When dealing with user input I almost always trim it (Just because they love to insert random white spaces at the beginnings and end) and check to see if it's empty. This could probably be put into a function that also either shows an error or exits the program on "Empty" and otherwise returns a string.
If you often want int values, write a second function that calls the first. Have the second function return an int, but have it catch the exception if the text is invalid and prompt the user again. You could even have this function take a "Range" of integers as a parameter and provide a prompt. So what you have above could look like this:
playerCount = getUserInput("Please enter the number of users", 1, 2);
The rest is wrapped in simple non-redundant functions.
Won't write the code for you because A) it's probably a homework assignment and the fun part is actually coding it and B) someone else probably will provide a full solution with code before I'm done typing this :(
Good luck.

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

Not accepting user input eclipse java

I've been searching overflow questions and googling it for about half an hour and can't find an answer for this.
At first I thought it might be that I'm not closing my Scanner object. I added
inp.close();
after all my code,but still nothing.
I'm using Eclipse to create a simple Binary Search algorithm.
My problem is that it is not keeping my input. And what's even weirder is that it only accepts "5".
After pressing enter it only creates more spaces. It doesn't move on to the rest of the program.
I've also tried entering more values under the "skipped" ones without any success.
Here's some screenshots
nextInt() reads scans the next token of the input as an int.
If the input is not an int, then an InputMismatchException is thrown.
You can use next() to read the input, whatever its type is. And you can hasNextInt() to make sure the next input is an int:
Scanner inp = new Scanner(System.in);
if(inp.hasNext()) {
if(inp.hasNextInt()) {
int n = inp.nextInt();
// do something with n
} else {
String s = inp.next();
// do something with s
}
}
Actually, I have a theory - your Scanner code is working just fine, it's your binary search code that's broken. Whatever it's doing works on an input of 5 but falls into an infinite loop for other inputs.
Consider breaking up your input parsing code from your binary searching code (e.g. do input parsing in main() and define a binarySearch() function that main() calls) so that you can test them separately.

Categories