What does hasNext() in a While do? - java

I'm new to Java and I'm trying to read data from a .txt file. I've implemented a Scanner object 'in' Scanner in=new Scanner("file.txt"); and then down the code a while loop to traverse through the content of the file.There are multiple rows of data in the file and in each row there are three strings (security number ,First name ,Last name : 01 Thomas Anderson)
while(in.hasNext()){
String ss = in.next();
String FName=in.next();
String LName=in.next();
System.out.printf("SSN: %s, FirstName: %s, LastName: %s \n",ss,FName,LName);
}
So, what does the hasNext() method do? Does it look for end of the row or for the last row in the file or.... ?
Please elaborate on the working of the above snippet (mentioning the next() method too).

I do recommend looking at the Javadoc, but I'll explain it for you as simple as I can.
Basically, the hasNext() method returns true if the given document contains another string. Hence why the snippet will loop if said document has another string. Once there are no more Strings in the entire document, hasNext() returnsfalse.
Here's an example of the next() method:
String myString = myScanner.next();
This makes myString equal to the next string in the given document.

Javadoc says:
hasNext
public boolean hasNext()
Returns true if this scanner has another token in its input. This
method may block while waiting for input to scan. The scanner does not
advance past any input.
next
public String next()
Finds and returns the next complete token from this scanner. A
complete token is preceded and followed by input that matches the
delimiter pattern. This method may block while waiting for input to
scan, even if a previous invocation of hasNext() returned true.
To read all your file rows you'll have to check if there are tokens every line. Then you call 3 times the next method since you know there will be 3 tokens per line:
import java.io.File;
import java.util.Scanner;
public class FLoader {
public void load(String path) {
Scanner in = null;
try {
in = new Scanner(new File(path));
while (in.hasNext()) {
String ss = in.next();
String FName = in.next();
String LName = in.next();
System.out.printf("SSN: %s, FirstName: %s, LastName: %s \n", ss, FName, LName);
}
} catch (Exception e) {
System.err.println("Loading file failed");
e.printStackTrace();
System.exit(-1);
}
}
}

Related

Method never reaching an if statement despite, its conditions being met

I'm trying to scan through a txt.file with name and gender and my code is supposed to take the user input of a name and gender, read through the txt file to see if that combination exists, and then either return the information (if there is a match) or say there was no match.
I put place holder S.O.P statements just to help debug and it shows that it reaches the return statement where it's supposed to return the info from the txt file because it's found that match, but the method fails to pass the if statement where it returns the user info once there is a match, even if the info the user puts in is one that is supposed to have a match.
The code is here :
public class Draft {
public static void main(String[] args) throws FileNotFoundException {
Scanner console = new Scanner(System.in);
Scanner input = new Scanner(new File("names.txt"));
ProgramIntro();
System.out.print("name? ");
String userName = console.nextLine();
System.out.print("sex (M or F)? ");
String userGender = console.nextLine();
System.out.print(searchInfo (input, userName, userGender));
}
//searches file for user input match and returns value depending on whether a match exists
public static String searchInfo (Scanner input, String userName, String userGender) {
//goes through the file until there are no more entries
while (input.hasNextLine()) {
System.out.print("blach");
//concatenates one line of file into one string
String line = input.nextLine();
//turns the focus into just one line
Scanner lineScan = new Scanner(line);
//runs loop just on one single line
while (!lineScan.hasNextInt()) {
System.out.print("bafdjkf");
//sets the first thing in a line (the name) as String babyName
String babyName = lineScan.next();
System.out.print(babyName);
//sets the first thing in a line (the name) as String gender
String gender = lineScan.next();
System.out.println(gender);
if (userName.equalsIgnoreCase(babyName) && userGender.equalsIgnoreCase(gender)) { //THE PROBLEM LINE
System.out.print("jgfgfgfgfgfg");
System.out.println(line);
return line;
}
}
}
return "name/sex combination not found";
}
And it never reaches the if statement because the placeholder S.O.P in the if statement never prints.
blachbafdjkfCaleighF //Caleigh is the name we tested
blachbafdjkfRisaF
blachbafdjkfRoninM
blachbafdjkfFronaF
blachbafdjkfDanaF
blachbafdjkfJesusM
blachbafdjkfHarleyM
blachbafdjkfJadaF
Where is the logic error in this program?
How come the program goes back to the first while loop and starts scanning through the rest of the names in the list despite finding a match?
Because you call that method twice:
searchInfo (input, userName, userGender);
System.out.print(searchInfo (input, userName, userGender));
You have to either skip the first call or store the result of the first call in a variable and instead of calling the method a second time print that variable.

HW : search for input string in text document

this is my first post so forgive me if i have posted incorrectly. I have a task that i need to complete but i cant get it to work properly. the compiler that i use is bluej. what i need to do is to use scanner to read a text file and compare a user input to the text file. if the input string compares then it should print out that ""The word is on the text file". Unfortunately i cant get this to work. My code reads the file because it prints out to the console but no comparison it s happening. please have a look at my code and give me some pointers. i have been trying to use .equals():
private boolean searchFromRecord(String recordName, String word) throws IOException
{
// Please write your code after this line
File file = new File(recordName);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
for(int i = 0; scanner.hasNextLine(); i++){
String compare = scanner.nextLine();
IO.outputln("word#" + i + ":" + compare);
}
scanner.close();
if (scanner.equals(word)){
return true;
} else{
return false;
}
}
return true;
}
this is what i get output in the console:
Input a word: IRON
AA 888
word#0:BULLET
word#1:1
word#2:AE 1688
word#3:CHEERS
word#4:GAMES
word#5:IRON MAN
word#6:WOLF
word#7:Testing
word#8:Wonderful
The word "IRON" is not in the record.
Here are some problems, along with why they are problems & a suggestion on how they could be fixed:
Problem: closing a scanner within the a loop that uses it will cause an exception. Reason: after we go through the loop once, the scanner will be closed. when we loop through again, an error will occur since the loop uses the scanner, which means the scanner should be "open". Possible solution: move scanner.close() to after the while loop.
Problem: we shouldn't return true at the end of this method. Reason: I'm guessing that this method is supposed to return true if the word is found, and false otherwise. Now, the only way to get to this return statement is if our word doesn't exist in the recordFile; it should return false. Possible solution: return false at the end of the method instead.
Problem: the first line in recordFile will never be checked for equality with word Reason: each method call of scanner.nextLine() will return each line from the recordFile as a String once and only once. In your code, it is called once in the beginning of the while loop's body, but not used to compare with word, then after, it is used in the for loop for comparison Possible solution: remove the line: System.out.println(scanner.nextLine());.
Problem: scanner.equals(word) will probably always return false. Reason: scanner is a Scanner, and word is a String, they should never be equal. Possible solution: replace scanner.equals(word) with compare.equals(word)
Problem: word is not actually compared with each compare. Reason: it is outside the for loop. Possible solution: move the if else block into the end of the for loop's body.
I don't think the while loop is really needed. I strongly recommend that the while loop, is removed, but keep the body.
Problem: Moving the if else block into the for loop, and above the scanner.close() means that the scanner.close() will never be run. Reason: once a return statement is executed, the flow of control immediatly exits the method, and returns to where the method was invoked which makes code after return statements useless. Possible solution: instead of returning right away, declare some sort of boolean variable that will store the return value. have the return value be modified throughout the method, then return the variable at the very end, after scaner.close()
There are many many other ways to fix each of these problems other than the ones suggested here.
I hope you find this helpful! :)
your code, refactored to implement the suggested solutions above:
private boolean searchFromRecord(String recordName, String word) throws IOException {
// Please write your code after this line
Boolean wordFound = false; // indicates if word exists in recordFile.
File file = new File(recordName); // file at path "recordName"
Scanner scanner = new Scanner(file); // reads records from "file"
// iterate through the recordFile, to see if "word" already exists
// within recordFile.
for(int i = 0; scanner.hasNextLine(); i++) {
// read the record from the file
String compare = scanner.nextLine();
IO.outputln("word#" + i + ":" + compare);
// compare the record with our word
if (compare.equals(word)){
wordFound = true;
break; // bail out of loop, our work here is done
}
}
// clean up, and return...
scanner.close();
return wordFound;
}
First, scanner is not a String and it will not equal a String. Second, you are dropping lines - scanner.nextLine() gets the next line, and you print it (but don't save it or compare it). I think you wanted something more like this,
// eats and tosses input.
// System.out.println(scanner.nextLine());
String line = scanner.nextLine();
for(int i = 0; scanner.hasNextLine(); i++){
String compare = scanner.nextLine();
IO.outputln("word#" + i + ": " + compare + " to line: " + line);
if (line.contains(compare)){ // "IRON MAN" starts with "IRON", it doesn't equal IRON.
return true;
}
}
scanner.close();
return false; // <-- default.
Another flavor is to read the whole file into a String variable and look for specified String inside the String.
Code:
File file = new File("C:\\Users\\KICK\\Documents\\NetBeansProjects"
+ "\\SearchWordinFile\\src\\searchwordinfile\\words.txt");
String s="";
try(Scanner input = new Scanner(file)){
input.useDelimiter("\\A");
if (input.hasNext()) {
s = input.next();
}
}catch(Exception e){
System.out.println(e);
}
if(s.contains("IRON"))
System.out.println("I found IRON");
}
Output:
I found IRON
My File content
BULLET
1
AE 1688
CHEERS
GAMES
IRON MAN
WOLF
Testing
Wonderful

Printing a string backwards

I'm trying to print a string in reverse. i.e.
hello world
should come out as:
dlrow olleh
But the outcome only shows the reverse of the first word. i.e.
olleh
Any thoughts?
import java.util.Scanner;
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("Input a string:");
String s;
s = input.next();
String original, reverse = "";
original = s;
int length = original.length();
for ( int i = length - 1 ; i >= 0 ; i-- )
reverse = reverse + original.charAt(i);
System.out.println("Reverse of entered string is: "+reverse);
input.close();
}
}
Using input.next() only stores the next word in the variable (only "hello"). Try this:
System.out.println("Input a string:");
String s;
s = input.nextLine();
System.out.println("entered: " + s);
The line
s=input.next()
will only take one word.
So to get the whole line 'hello world', you've to use the nextLine() function.
s = input.nextLine();
Your scanner object returns only the next complete token through the input.next() method. A token is considered complete when there is a whitespace character. Use the nextLine() method of the scanner to get the complete input if you are using multiple words.
new StringBuilder("hello world").reverse().toString();
Maybe much more simpler.
use s.nextline() instead of s.next() as s.next() read only first token string
Scanner sc= new Scanner(System.in);
String s = sc.nextLine();
System.out.println(new StringBuilder(s).reverse().toString());
From Scanner javadoc:
public String next()
Finds and returns the next complete token from this scanner. A
complete token is preceded and followed by input that matches the
delimiter pattern. This method may block while waiting for input to
scan, even if a previous invocation of hasNext() returned true.
What happens is that the token delimiter may not be what you're expecting (newline, for instance).
If you wish your program to read the entire line input by the user, you might want to use Scanner.nextLine(), which will read the entire line input by the user, or maybe Scanner.next(String delimiter), which will allow you to enter the desired token delimiter.
Change s = input.next() to s = input.nextLine()
I can't really write some source code but maybe try using two different inputs. After that add each string to it's own variable. After that, reverse them both and add them together as an output.

What's the difference between next() and nextLine() methods from Scanner class?

What is the main difference between next() and nextLine()?
My main goal is to read the all text using a Scanner which may be "connected" to any source (file for example).
Which one should I choose and why?
I always prefer to read input using nextLine() and then parse the string.
Using next() will only return what comes before the delimiter (defaults to whitespace). nextLine() automatically moves the scanner down after returning the current line.
A useful tool for parsing data from nextLine() would be str.split("\\s+").
String data = scanner.nextLine();
String[] pieces = data.split("\\s+");
// Parse the pieces
For more information regarding the Scanner class or String class refer to the following links.
Scanner: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
String: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
next() can read the input only till the space. It can't read two words separated by a space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
For reading the entire line you can use nextLine().
From JavaDoc:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
next(): Finds and returns the next complete token from this scanner.
nextLine(): Advances this scanner past the current line and returns the input that was skipped.
So in case of "small example<eol>text" next() should return "small" and nextLine() should return "small example"
The key point is to find where the method will stop and where the cursor will be after calling the methods.
All methods will read information which does not include whitespace between the cursor position and the next default delimiters(whitespace, tab, \n--created by pressing Enter). The cursor stops before the delimiters except for nextLine(), which reads information (including whitespace created by delimiters) between the cursor position and \n, and the cursor stops behind \n.
For example, consider the following illustration:
|23_24_25_26_27\n
| -> the current cursor position
_ -> whitespace
stream -> Bold (the information got by the calling method)
See what happens when you call these methods:
nextInt()
read 23|_24_25_26_27\n
nextDouble()
read 23_24|_25_26_27\n
next()
read 23_24_25|_26_27\n
nextLine()
read 23_24_25_26_27\n|
After this, the method should be called depending on your requirement.
What I have noticed apart from next() scans only upto space where as nextLine() scans the entire line is that next waits till it gets a complete token where as nextLine() does not wait for complete token, when ever '\n' is obtained(i.e when you press enter key) the scanner cursor moves to the next line and returns the previous line skipped. It does not check for the whether you have given complete input or not, even it will take an empty string where as next() does not take empty string
public class ScannerTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int cases = sc.nextInt();
String []str = new String[cases];
for(int i=0;i<cases;i++){
str[i]=sc.next();
}
}
}
Try this program by changing the next() and nextLine() in for loop, go on pressing '\n' that is enter key without any input, you can find that using nextLine() method it terminates after pressing given number of cases where as next() doesnot terminate untill you provide and input to it for the given number of cases.
next() and nextLine() methods are associated with Scanner and is used for getting String inputs. Their differences are...
next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
import java.util.Scanner;
public class temp
{
public static void main(String arg[])
{
Scanner sc=new Scanner(System.in);
System.out.println("enter string for c");
String c=sc.next();
System.out.println("c is "+c);
System.out.println("enter string for d");
String d=sc.next();
System.out.println("d is "+d);
}
}
Output:
enter string for c
abc def
c is abc
enter string for d
d is def
If you use nextLine() instead of next() then
Output:
enter string for c
ABC DEF
c is ABC DEF
enter string for d
GHI
d is GHI
In short: if you are inputting a string array of length t, then Scanner#nextLine() expects t lines, each entry in the string array is differentiated from the other by enter key.And Scanner#next() will keep taking inputs till you press enter but stores string(word) inside the array, which is separated by whitespace.
Lets have a look at following snippet of code
Scanner in = new Scanner(System.in);
int t = in.nextInt();
String[] s = new String[t];
for (int i = 0; i < t; i++) {
s[i] = in.next();
}
when I run above snippet of code in my IDE (lets say for string length 2),it does not matter whether I enter my string as
Input as :- abcd abcd or
Input as :-
abcd
abcd
Output will be like
abcd
abcd
But if in same code we replace next() method by nextLine()
Scanner in = new Scanner(System.in);
int t = in.nextInt();
String[] s = new String[t];
for (int i = 0; i < t; i++) {
s[i] = in.nextLine();
}
Then if you enter input on prompt as -
abcd abcd
Output is :-
abcd abcd
and if you enter the input on prompt as
abcd (and if you press enter to enter next abcd in another line, the input prompt will just exit and you will get the output)
Output is:-
abcd
From javadocs
next() Returns the next token if it matches the pattern constructed from the specified string.
nextLine() Advances this scanner past the current line and returns the input that was skipped.
Which one you choose depends which suits your needs best. If it were me reading a whole file I would go for nextLine until I had all the file.
From the documentation for Scanner:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
From the documentation for next():
A complete token is preceded and followed by input that matches the delimiter pattern.
Just for another example of Scanner.next() and nextLine() is that like below :
nextLine() does not let user type while next() makes Scanner wait and read the input.
Scanner sc = new Scanner(System.in);
do {
System.out.println("The values on dice are :");
for(int i = 0; i < n; i++) {
System.out.println(ran.nextInt(6) + 1);
}
System.out.println("Continue : yes or no");
} while(sc.next().equals("yes"));
// while(sc.nextLine().equals("yes"));
Both functions are used to move to the next Scanner token.
The difference lies in how the scanner token is generated
next() generates scanner tokens using delimiter as White Space
nextLine() generates scanner tokens using delimiter as '\n' (i.e Enter
key presses)
A scanner breaks its input into tokens using a delimiter pattern, which is by default known the Whitespaces.
Next() uses to read a single word and when it gets a white space,it stops reading and the cursor back to its original position.
NextLine() while this one reads a whole word even when it meets a whitespace.the cursor stops when it finished reading and cursor backs to the end of the line.
so u don't need to use a delimeter when you want to read a full word as a sentence.you just need to use NextLine().
public static void main(String[] args) {
// TODO code application logic here
String str;
Scanner input = new Scanner( System.in );
str=input.nextLine();
System.out.println(str);
}
I also got a problem concerning a delimiter.
the question was all about inputs of
enter your name.
enter your age.
enter your email.
enter your address.
The problem
I finished successfully with name, age, and email.
When I came up with the address of two words having a whitespace (Harnet street) I just got the first one "harnet".
The solution
I used the delimiter for my scanner and went out successful.
Example
public static void main (String args[]){
//Initialize the Scanner this way so that it delimits input using a new line character.
Scanner s = new Scanner(System.in).useDelimiter("\n");
System.out.println("Enter Your Name: ");
String name = s.next();
System.out.println("Enter Your Age: ");
int age = s.nextInt();
System.out.println("Enter Your E-mail: ");
String email = s.next();
System.out.println("Enter Your Address: ");
String address = s.next();
System.out.println("Name: "+name);
System.out.println("Age: "+age);
System.out.println("E-mail: "+email);
System.out.println("Address: "+address);
}
The basic difference is next() is used for gettting the input till the delimiter is encountered(By default it is whitespace,but you can also change it) and return the token which you have entered.The cursor then remains on the Same line.Whereas in nextLine() it scans the input till we hit enter button and return the whole thing and places the cursor in the next line.
**
Scanner sc=new Scanner(System.in);
String s[]=new String[2];
for(int i=0;i<2;i++){
s[i]=sc.next();
}
for(int j=0;j<2;j++)
{
System.out.println("The string at position "+j+ " is "+s[j]);
}
**
Try running this code by giving Input as "Hello World".The scanner reads the input till 'o' and then a delimiter occurs.so s[0] will be "Hello" and cursor will be pointing to the next position after delimiter(that is 'W' in our case),and when s[1] is read it scans the "World" and return it to s[1] as the next complete token(by definition of Scanner).If we use nextLine() instead,it will read the "Hello World" fully and also more till we hit the enter button and store it in s[0].
We may give another string also by using nextLine(). I recommend you to try using this example and more and ask for any clarification.
The difference can be very clear with the code below and its output.
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
List<String> arrayList2 = new ArrayList<>();
Scanner input = new Scanner(System.in);
String product = input.next();
while(!product.equalsIgnoreCase("q")) {
arrayList.add(product);
product = input.next();
}
System.out.println("You wrote the following products \n");
for (String naam : arrayList) {
System.out.println(naam);
}
product = input.nextLine();
System.out.println("Enter a product");
while (!product.equalsIgnoreCase("q")) {
arrayList2.add(product);
System.out.println("Enter a product");
product = input.nextLine();
}
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println("You wrote the following products \n");
for (String naam : arrayList2) {
System.out.println(naam);
}
}
Output:
Enter a product
aaa aaa
Enter a product
Enter a product
bb
Enter a product
ccc cccc ccccc
Enter a product
Enter a product
Enter a product
q
You wrote the following products
aaa
aaa
bb
ccc
cccc
ccccc
Enter a product
Enter a product
aaaa aaaa aaaa
Enter a product
bb
Enter a product
q
You wrote the following products
aaaa aaaa aaaa
bb
Quite clear that the default delimiter space is adding the products separated by space to the list when next is used, so each time space separated strings are entered on a line, they are different strings.
With nextLine, space has no significance and the whole line is one string.

Displaying specific words in a .txt file using a scanner

I'm stuck and need your help (yes, it's homework), what I'm trying to do is get my code to read the contents in the text file and output the words by specific words. For example I want it to output all words that start with letter "g".
Here's a pseudocode code if I didn't explain that well:
BEGIN
Get the initial letter from the user
While there are more entries in the file
Get the next personal name
Get the next surname
Get the next year info
If the surname starts with the initial letter
Output the person name, surname and year info
End while
END
So far I've managed to get this done, and now I'm stuck where you output the names correctly. Any help or tutorials will be appreciated.
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
public class PrimeMinisters
{
public static void main(String[] args) throws FileNotFoundException
{
// ask the user for the first letter
Scanner keyboard = new Scanner(System.in);
System.out.print("What is the first letter? ");
String input = keyboard.next().toLowerCase();
char firstLetter = input.charAt(0);
// open the data file
File pmFile = new File ("OZPMS.txt");
// create a scanner from the file
Scanner pmInput = new Scanner (pmFile);
// read one line of data at a time, processing each line
while(pmInput.hasNext())
{
String names = pmInput.next();
System.out.println(names);
}
// be polite and close the file
pmInput.close();
}
}
I'd recommend using nextLine() over next(). From this you would then use the String's startsWith(String stringsequence) method which returns a boolean to get all the values beginning with the letter of your choice:
while(pmInput.hasNextLine())
{
String names = pmInput.nextLine();
System.out.println(names);
if(names.startsWith("g")) {
//the name begins with letter g do whatever
}
}
You can have a look at more methods for String here: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
Since your requirements state to look at the surname's first letter, it will be easier to tokenize each line while you read it (while checking to see if the user input is the first letter of the surname). Assuming that the line is in the order that you stated above, the surname will be token #2 (index 1 of the array).
public class PrimeMinisters
{
public static void main(String[] args) throws FileNotFoundException
{
// ask the user for the first letter
Scanner keyboard = new Scanner(System.in);
System.out.print("What is the first letter? ");
String input = keyboard.next().toLowerCase();
char firstLetter = input.charAt(0);
// open the data file
File pmFile = new File ("OZPMS.txt");
// create a scanner from the file
Scanner pmInput = new Scanner (pmFile);
// read one line of data at a time, processing each line
while(pmInput.hasNextLine())
{
String names = pmInput.nextLine();
// Break line into tokens. This is assuming that there are only
// 3 strings per line in the following order (personal name, surname, yearinfo)
//
String[] info = names.split("\\s");
// Check 2nd string in line (since you are looking for the first character in
// the surname and not the personal name.
//
if(info[1].startsWith(input))
{
System.out.println(info[0] + "\t" + info[1] + "\t" + info[2]);
}
}
// be polite and close the file
pmInput.close();
}
}

Categories