Displaying specific words in a .txt file using a scanner - java

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();
}
}

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.

my program reads from the file but cant find the words

So my program knows where the file is and it can read how many words it has, however, I am trying to compare words to count the occurrences of a word that i will use with a scanner.
The program says i can't convert string to a boolean which i understand but how would i be able to make it happen?
can I get an answer why it runs but doesn't allow me to find the word to look for
thanks
import java.util.*;
import java.io.*;
public class wordOccurence {
public static void main(String[] args) throws IOException {
{
int wordCount=0;
int word =0;
Scanner scan=new Scanner(System.in);
System.out.println("Enter file name");
System.out.println("Enter the word you want to scan");
String fileName=scan.next().trim();
Scanner scr = new Scanner(new File(fileName));
// your code goes here ...
while(scr.nextLine()){
String word1 = scr.next();
if (word1.equals(scr)){
word++;
}
}
System.out.println("Total words = " + word);
}
}
}
At present you are only checking if there is a next line available:
while(scr.hasNextLine()){
but you are not fetching it. Its like you are staying at the same position in the file forever.
To fetch the next line, you can make use of
scanner.nextLine()

String array name search

So I have a file which has all presidents in it - their first name, middle initial (if any), and last name.
The file needs to be read in, and a user can enter a president's name to search for it, and that president should be displayed.
I have it displaying the president if a user searches by first name or by last name, but not by both.
For example, the external file contains:
George,Washington,(1789-1797)
Franklin,D.,Roosevelt,(1933-1945)
... and so on with all the presidents
I need the user to be able to either type in the first name, the last name, or both first and last name and get the desired result (the date is irrelevant for the most part).
Tried lots of different things, but not getting there as far as displaying the president if user searches by first and last name.
Here is what I got so far:
public class NameSearch {
public static void main(String[] args) throws IOException {
try {
// read from presidents file
Scanner presidentsFile = new Scanner(new File("Presidents.txt"));
// scanner for user input
Scanner keyboard = new Scanner(System.in);
// create array list of each line in presidents file
ArrayList<String> presidentsArrayList = new ArrayList<String>();
// prompt user to enter a string to see if it matches with a president's name
System.out.println("Enter a search string of letters to find a president match: ");
// store user input
String userInput = keyboard.nextLine();
// add president file info to array list linesInPresidentFile
while (presidentsFile.hasNextLine()) {
presidentsArrayList.add(presidentsFile.nextLine());
} // end while loop
String presidentNamesArray[] = presidentsArrayList.toArray(new String[presidentsArrayList.size()]);
String results = searchArray(presidentNamesArray, userInput);
//System.out.println("\nThe presidents who have \"" + userInput + "\" as part of their name are: ");
} catch (FileNotFoundException ex) {
// print out error (if any) to screen
System.out.println(ex.toString());
} // end catch block
} // end main
// method to search for a specific value in an array
public static String searchArray(String array[], String value) {
for (int i = 0; i < array.length; i++) {
if (array[i].toLowerCase().contains(value.toLowerCase())) {
String splitter[] = array[i].split(" ,");
System.out.println(Arrays.toString(splitter));
}
}
return Arrays.toString(array);
}
}
There is another way in which I might have implemented this.Read the file inputs and stored them as objects (class with lname, fname and year perhaps). In this way you can search for lname from user input, match it up with its corresponding fname (as same objects). The creation can be done once and searching can be done in a while loop implementing users consent of continuing the search.
//define your class like this:
static int i; //to keep a track of number of objects
public class dummy{
string fname;
string lname;
string year;
};
while the file content exists:
read the line
dummy dobj[i++] = new dummy();//allocate memory for the object
split the different parameters (fname, lname, year) from the read line
put these read parameters into the object
dobj[i].fname = first;
dobj[i].lname = second;
dobj[i].year = y;
//ask your user to enter the query in a specified format
//if he enters lname, compare your input to all the object's lname, and so on
//in case of lname && fname, compare your input to the lname first and then check for the corresponding objects fname, if they match.. display
Actually, there are many ways in which you can achieve what you wish to program. You can ask use the array list indices to solve it. If you take in the input from the user in a particular format, you can map it to the index in that list. Further, if you want to use first name and last name together, you may use these index representing the first and last name to come from same list.
The reason you may have problems searching by both first and last names is because you have to match your input exactly (ignoring case of course). What I mean is if you use George Washington as input, your program will not find a match for the George,Washington,(1789-1797) line. This is because your program treats George Washington as one string. Note: the input is missing the comma, so it will not be considered a substring of George,Washington,(1789-1797). If you used George,Washington as your input string, then your program would print the George Washington line. Your program just searches if the input string is a substring of any of the lines in your file. It does not search for a first name or last name specifically. If you used in as your input string, then you would get a match for both George Washington and Franklin D. Roosevelt.What you could do is take your input data and split it and search for each of the terms. You can either accept lines that match all of the terms provided, or at least one of the terms provided.
public static String searchArray(String array[], String value) {
// Uses both blank spaces and commas as delimiters
String[] terms = value.toLowerCase().Split("[ ,]");
for (int i = 0; i < array.length; i++) {
String line = array[i].toLowerCase();
boolean printIfAllMatch = true;
boolean printIfAtLeastOneMatches = false;
for(int j = 0 ; j < terms.length; j++) {
// Check that all terms are contained in the line
printIfAllMatch &= line.Contains(terms[j]);
// Check that at least one term is in the line
printIfAtLeastOneMatches |= line.Contains(terms[j]);
}
String splitter[] = array[i].split(" ,");
if (printIfAllMatch) {
System.out.println(Arrays.toString(splitter));
}
if(printIfAtLeastOneMatches) {
System.out.println(Arrays.toString(splitter));
}
}
//I'm not sure why you're returning the original array as a string
//I would think it would make more sense to return an Array of filtered data.
return Arrays.toString(array);
}
This does not take name ordering into account. If that's what you're going for, then I would suggest making a class and parsing each line in the file as an new object and trying to match the first term provided with the first name and second term provided with the last name, or something to that effect.

String.replace() method not printing full string in java

I'm trying to do some homework for my computer science class and I can't seem to figure this one out. The question is:
Write a program that reads a line of text and then displays the line, but with the first occurrence of hate changed to love.
This sounded like a basic problem, so I went ahead and wrote this up:
import java.util.Scanner;
public class question {
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a line of text:");
String text = keyboard.next();
System.out.println("I have rephrased that line to read:");
System.out.println(text.replaceFirst("hate", "love"));
}
}
I expect a string input of "I hate you" to read "I love you", but all it outputs is "I". When it detects the first occurrence of the word I'm trying to replace, it removes the rest of the string, unless it's the first word of the string. For instance, if I just input "hate", it will change it to "love". I've looked at many sites and documentations, and I believe I'm following the correct steps. If anyone could explain what I'm doing wrong here so that it does display the full string with the replaced word, that would be fantastic.
Thank you!
Your mistake was on the keyboard.next() call. This reads the first (space-separated) word. You want to use keyboard.nextLine() instead, as that reads a whole line (which is what your input is in this case).
Revised, your code looks like this:
import java.util.Scanner;
public class question {
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a line of text:");
String text = keyboard.nextLine();
System.out.println("I have rephrased that line to read:");
System.out.println(text.replaceFirst("hate", "love"));
}
}
Try getting the whole line like this, instead of just the first token:
String text = keyboard.nextLine();
keyboard.next() only reads the next token.
Use keyboard.nextLine() to read the entire line.
In your current code, if you print the contents of text before the replace you will see that only I has been taken as input.
As an alternate answer, build a while loop and look for the word in question:
import java.util.Scanner;
public class question {
public static void main(String[] args)
{
// Start with the word we want to replace
String findStr = "hate";
// and the word we will replace it with
String replaceStr = "love";
// Need a place to put the response
StringBuilder response = new StringBuilder();
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a line of text:");
System.out.println("<Remember to end the stream with Ctrl-Z>");
String text = null;
while(keyboard.hasNext())
{
// Make sure we have a space between characters
if(text != null)
{
response.append(' ');
}
text = keyboard.next();
if(findStr.compareToIgnoreCase(text)==0)
{
// Found the word so replace it
response.append(replaceStr);
}
else
{
// Otherwise just return what was entered.
response.append(text);
}
}
System.out.println("I have rephrased that line to read:");
System.out.println(response.toString());
}
}
Takes advantage of the Scanner returning one word at a time. The matching will fail if the word is followed by a punctuation mark though. Anyway, this is the answer that popped into my head when I read the question.

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.

Categories