The current code that I have reads only the last line of the file. Can someone help me establish a way so that the code reads a file line by line?
import java.util.*;
import java.io.*;
public class Searcher extends File {
Scanner scn;
public Searcher(String filename) {
super(filename);
}
public void search(String input)
{
try {
scn = new Scanner(this);
String data = "";
while (scn.hasNext()) {
data = scn.nextLine();
}
int count = 0, fromIndex = 0;
while ((fromIndex = data.indexOf(input, fromIndex)) != -1) {
count++;
fromIndex++;
}
System.out.println("Total occurrences: " + count);
scn.close();
} catch (Exception e) {
System.out.println("Cant find file ");
}
}
public static void main(String[] args) {
Searcher search = new Searcher("src/ihaveadream.txt");
search.search("we");
}
}
appreciate any help !
while (scn.hasNext()) {
data = scn.nextLine();
}
You are replacing the value every time so you end up with the last value as that's what it gets set to in the end. Perhaps you wanted to append?
while (scn.hasNext()) {
data = data + scn.nextLine();
}
Good luck.
Your problem:
while (scn.hasNext()) {
data = scn.nextLine(); // right here
}
each next line replaces previous line.
Depending on what you need you can either:
make all lines as one String
data = data + scn.nextLine();
// another syntax to do the same:
data += scn.nextLine();
or use List to keep each line as separate element:
List<String> dataList = new ArrayList<>();
while (scn.hasNext()) {
dataList.add(scn.nextLine());
}
As everyone has already suggested, you are replacing the the data in your data variable in the while loop, and since the loop runs till the end of the file is reached, only the last line is stored in the data variable, and any further processing on data would get you results only from the last line, so what you can do is what everybody else here suggested, or you can try this as an alternative solution (close the while loop after you check for index values):
public void search(String input)
{
int count = 0, fromIndex = 0; //moved outside so that we don't reset it to 0 with every iteration of the loop
try {
scn = new Scanner(this);
String data = "";
while (scn.hasNext()) {
data = scn.nextLine();
//} instead of here
//int count = 0, fromIndex = 0; move these variables outside of the loop
while ((fromIndex = data.indexOf(input, fromIndex)) != -1) {
count++;
fromIndex++;
}
} //close it here
System.out.println("Total occurrences: " + count);
scn.close();
} catch (Exception e) {
System.out.println("Cant find file ");
}
}
Related
Here is my NameRecord constructor class:
public class NameRecord {
String firstName;
int count;
public NameRecord(String name, int count){
this.firstName = name;
this.count = count;
}
#Override
public String toString() {
return firstName + " - " + count + " registered births.";
}
public String getFirstName() {
return firstName;
}
public int getCount() {
return count;
}
}
And here is what I have so far of the actual program:
public class Names {
public final int MAX_NAMES = 3;
NameRecord[] boyNames = new NameRecord[MAX_NAMES];
String boysFile = "data/boynames.txt";
#Override
public String toString() {
String result = "";
for (NameRecord record : boyNames)
result += record + "\n";
return result;
}
public void loadNamesFromFile() {
try {
BufferedReader stream = new BufferedReader(new FileReader("Data/boysnames.txt"));
} catch (Exception e)
{
System.out.println("File not found");
}
}
}
Basically, the program reads a file and determines if the name is on the boys list or girls list txt files, and then outputs if it is on the list, and if so how many times it was used. I am only working with boys for right now to keep confusion to a minimum. My question is, in the loadNamesFromFile method, how do I add information from the file to the boyNames array. I know the NameRecord calls for the name and the count, but I'm not sure how to retrieve that information from the file and add it to the array. I have included the top three names from the file below, the name is of course the first name and the number is the number of times it was used, or count.
Jacob 29195
Michael 26991
Joshua 24950
First of all if it is possible to have your file structure like this
Jacob;29195
Michael;26991
Joshua;24950
to make it more easy to develop the solution
and now this is how you can read the file lines and store them into your tabel
public void loadNamesFromFile() {
try {
BufferedReader stream = new BufferedReader(new FileReader("Data/boysnames.txt"));
String currentLine ="";
int i = 0;
while(curentLine = stram.readLine()) {
String [] record = currentLine.split(";");
NameRecord = name = new NameRecord(record[0], Integer.parseInt(record[1]);
boyNames[i] = name;
i++;
}
} catch (Exception e)
{
System.out.println("File not found");
}
}
First of all you should add a scanner for the file in order to read what is in the file. After that u keep reading the file and add the information untill there is no more content in the file. Besides this I would use an ArrayList of NameRecord for being more flexible with the number of names.
Im assuming that the content of your file is always the same (given your example).
public class Names {
try {
ArrayList<NameRecord> boyNames = new ArrayList<>();
public void loadNamesFromFile() {
File file = new File("Data/boysnames.txt");
Scanner sc = new Scanner(file);
while(sc.hasNextLine()) {
boyNames.add(new NameRecord(sc.next(), sc.nextInt()));
}
sc.close();
}
} catch(IOException e) {
System.err.println(e);
}
}
My suggestion is to read all the contents of the file i.e., all the names, in a single String variable. Then, iterate over each word and count the number of occurrences and add the info to the array. Let's use Scanner to read the file.
I presume that the length of the array boyNames[] is equal to the number of unique names in the file.
Scanner boys = new Scanner(new File("Data/boys.txt"));
int a,i,n=0,c,b;
String con = "", x; //con holds all names
//reading the names
while(boys.hasNext())
con+= boys.next()+" ";
b = con.split(" ").length; //b = total number of names in the file
for(i=0; i<b; i++){
x = con.split(" ")[i];
if(!x.equals("*")){
c = 0; a = 0;
//counting frequency of x in con
while(con.indexOf(x, a) != -1){
c++; a = con.indexOf(x, a) + x.length() + 1;
}
//adding name and frequency to array
boyNames[n++] = new NameRecord(x, c);
con = con.replaceAll(x, "*"); //removing all instances of x from con
}
}
The boyNames[] array now stores the names and their respective frequencies in the file.
I am making an app that keeps username and scores from a game in a txt file. The concept is that when it writes a new username and score to the txt file it should open the .txt file, read it and then make a clone of it adding a new uername and score entry in the txt file.
I am thinking of making this with 2 object arrays. The first is the one that is read in and the new will be the one is writen which will have one more entry.
So if player[i] is readen player[i+1] should be writen with new entry.
I am giving u the code below!
private Player[] myplayer=null;
private Player[] mynewplayer=null;
//open Players.txt
int i;
int n;
String filename="players.txt";
try
{
FileReader fp=new FileReader(filename);
BufferedReader bf=new BufferedReader(fp);
n=Integer.parseInt(bf.readLine());
myplayer=new Player[n];
int x=n+1;
mynewplayer=new Player[x];
for(i=0;i<n;i++)
{
String s=bf.readLine();
String user="",score="";
user=s.substring(0,s.indexOf(","));
s=s.substring(s.indexOf(",")+1);
score=s;
myplayer[i]=new Player(user,Double.parseDouble(score));
for(i=0;i<n;i++)
{
mynewplayer[i]= myplayer[i];
}
mynewplayer[x]=new Player(Username,Double.parseDouble(score));
}
bf.close();
fp.close();
}catch(IOException e)
{
System.out.println("Exception was "+e.getMessage());
}
//----------------------------------WRITE mytxt!-------------
n=myplayer.length;
try
{
filename="players.txt";
FileWriter fp=new FileWriter(filename);
fp.write(""+n+"\n");
for(i=0;i<n+1;i++)
fp.write(""+mynewplayer[i]+"\n");
fp.close();
}catch(IOException e)
{
System.out.println("Exception was "+e.getMessage());
}
//----------------------------------WRITE mytxt!-----------
//Get on Message
String s="";
for(i=0;i<mynewplayer.length;i++)
s=s+mynewplayer[i]+"\n";
JOptionPane.showMessageDialog(null,"Players are \n "+s);
Problem is that when it's written, it returns null for mynewplayer.
I suppose the mynewplayer doesnt really take the entries of the "myplayer" but neither writes the new username.
Compile doesnt show any errors. Just writes NULL to the textfile.
Ask me if u want further info on the code writen!
Thanks in advance!
Here is an edited version of your code, with some improvements and there should be a comment around code that I changed, explaining what I did.
Player[] myPlayer = null; // first word uncapitalized, every
Player[] myNewPlayer = null; // other word begins with a capital
//open Players.txt
int i, n; // combine the variables into 1 line
String filename = "players.txt";
try {
FileReader fp = new FileReader(filename);
BufferedReader bf = new BufferedReader(fp);
n = Integer.parseInt(bf.readLine());
// not needed
//myPlayer = new Player[n];
// NOT NEEDED int x = n + 1;
myNewPlayer = new Player[n + 1];
for (i = 0; i < n; i++) {
String s = bf.readLine();
String user, score; // combine variables, doesnt need to initalize them
String[] items = s.split(","); // Splits the line into array elements on every delimiter -> ,
//user = s.substring(0, s.indexOf(","));
//s = s.substring(s.indexOf(",") + 1);
//score = s;
user = items[0];
score = items[1];
// this line below isnt actually needed
//myPlayer[i] = new Player(user, Double.parseDouble(score));
// Create a new player clone, dont copy the previous one
myNewPlayer[i] = new Player(user, Double.parseDouble(score));
}
// We've read all the variables from the text file, now we create the last one
// Since myNewPlayer is (n+1) size, the range of the array is
// 0 to n
// the last index will be n New Score Variable
myNewPlayer[n] = new Player("Username variable", Double.parseDouble("22"));
bf.close();
fp.close();
} catch (IOException e) {
System.out.println("Exception was " + e.getMessage());
}
//----------------------------------WRITE mytxt!-------------
// This is called a ternary operator
// it is a 1 line if statement
// the format is like so
// booleanLogic ? trueAnswer Execution : falseAnswer Execution;
// if () { true }else { false }
n = myNewPlayer != null ? myNewPlayer.length : 0;
// CHANGED HERE - was using the first array rather than second
// dont need the 1st array
try {
filename = "players.txt";
FileWriter fp = new FileWriter(filename);
// Dont need "" before the items
fp.write(n + "\n");
for (i = 0; i < n; i++) {
fp.write(myNewPlayer[i] + "\n");
}
fp.close();
} catch (IOException e) {
System.out.println("Exception was " + e.getMessage());
}
//----------------------------------WRITE mytxt!-----------
//Get on Message
String s = "";
for (i = 0; i < myNewPlayer.length; i++) {
// s += ""; is like doing s = s + "";
s += myNewPlayer[i] + "\n";
}
JOptionPane.showMessageDialog(null, "Players are \n " + s);
I believe that your problem is this:
for(i=0;i<n;i++)
{
String s=bf.readLine();
String user="",score="";
user=s.substring(0,s.indexOf(","));
s=s.substring(s.indexOf(",")+1);
score=s;
myplayer[i]=new Player(user,Double.parseDouble(score));
for(i=0;i<n;i++)
{
mynewplayer[i]= myplayer[i];
}
mynewplayer[x]=new Player(Username,Double.parseDouble(score));
}
You have nested loops, which is fine, but they use the same counter (the variable i ).
So what is happening is the first line of the file is read, and then added to myplayer[0]. However, instead of just also adding it to mynewplayer[0], you start another loop on i. This loop:
for(i=0;i<n;i++)
{
mynewplayer[i]= myplayer[i];
}
is going to copy the first player into mynewplayer[0]...and then null into every other entry (since myplayer only has the firsdt element filled.
The problem is that after that loop completes, i will equal n, so when you get back to the top of the outer loop, the check $i
Perhaps what you should do is this:
for(i=0;i<n;i++)
{
String s=bf.readLine();
String user="",score="";
user=s.substring(0,s.indexOf(","));
s=s.substring(s.indexOf(",")+1);
score=s;
myplayer[i]=new Player(user,Double.parseDouble(score));
mynewplayer[i]= new Player(user,Double.parseDouble(score));
}
mynewplayer[x]=new Player(<the new username>,Double.parseDouble(<the new score>));
I have a .txt file with some text in it.
For example Hello, world.
I'd like to search the whole file and find out how many appearances a string has as well as the position of them, For example "wo" on the above text has one. That number should be placed in an edittext. However I only know how to search a specific char and not whole text, can you please help me? Thanks a lot
BufferedReader reader = new BufferedReader(new FileReader("somefile.txt"));
int ch;
char charToSearch='a';
int counter=0;
while((ch=reader.read()) != -1) {
if(charToSearch == (char)ch) {
counter++;
}
};
reader.close();
System.out.println(counter);
public static int countWord(String word, FileInputStream fis) {
BufferedReader in = new BufferedReader(new InputStreamReader(fis));
String readLine = "";
int count = 0;
try {
while ((readLine = in.readLine()) != null) {
String[] words = readLine.split(" ");
for (String s : words) {
if (s.contains(word))
count++;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return count;
}
You can use something like:
int nFound = 0;
String target = ".............Your long text..................";
String search = "find this"
int startIndex = 0
do
{
int index = target.indexOf(search, startIndex);
if(index !=-1)
{
// Found
nFound++;
// Here you have the index variable, which says you the position of the found match
/* DO your job */
/* Update the index to start the search again on the rest of the string, until no matches are found*/
startIndex = index+1;
}
else
break;
}while(true);
Before doing this, concatenate the whole text in "target" string, or dexecute the previous code for each line if you are sure the target string is not going to appear at the end of some line and the begining of the next line
If you are using Java 7, then according to this, you can get a String with the whole file in it:
String text = new String(Files.readAllBytes(Paths.get("file")), StandardCharsets.UTF_8);
Then, you can do this:
public void print(String word)
{
String tempStr = null;
int count = 0;
while (tempStr.indexOf(word) != -1)
{
System.out.printf("Position: %d, Count: %d\r\n", tempStr.indexOf(word), ++count);
tempStr = tempStr.substring(tempStr.indexOf(word) + word.length());
}
}
For simplicity, I would read a line and use "string.split(String regex)".
while(readLine) {
String[] str = readLine.split(regex);
//you can tell based on the array, how many matches and their position.
}
You can also use util.Scanner or regex.Pattern.
But if you are looking for performance, I think 'string.indexOf' is the best approach.
I have been working on this code for the day and am almost at the finish line. What I want is that the code should work as a clip card, remembering the number of purchased coffees, and awarding the customer a free coffee every 10th purchase. I'm writing to a file and reading from it in order for a customer to be able to continue his clip card where he left of last time. So to my problem...I have properly been able to write my "count" variable to a file, and it is storing it correctly. However, every time I run the program again it starts off a 0 and I don't see why. I need it to save the current count, and read the count once run again. For example, if a customer has previously purchased 7 coffees and is returning to the store, his counter needs to start at 7. For some reason it is not doing that.
Here's what I have so far:
public class FelixNeww {
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
FelixNeww f = new FelixNeww();
System.out.println(f.readFromFile());
while(true) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
entry = key.nextLine();
if(entry.compareTo(password) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought "
+ count + " coffe(s)");
f.saveToFile(count);
}
if(count == 10 && count != 0){
System.out.println("YOU'VE GOT A FREE COFFE!");
count = 0;
}
if(entry.compareTo(password) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
public void saveToFile(int count)
{
BufferedWriter bw = null;
try
{
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("C:\\Temp\\countStorage.txt"))));
bw.write(Integer.toString(count));
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(bw != null)
{
try
{
bw.close();
}
catch(IOException e) {}
}
}
}
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e) {}
}
}
return 0;
}
}
You are currently setting your count variable to 0. You should set it to the value that's in the file. Do this just before the while loop:
count = f.readFromFile();
while(true) {
You should also implement a way to gracefully exit the while loop. For example, if the user enters "q", you can execute the break; statement to exit the while loop. And after your while loop, call key.close(); to close the Scanner object.
The scope of count variable is local in both instances
public static void main(String [] args) {
Scanner key;
String entry;
int count = 0;
String password = "knusan01";
System.out.println(f.readFromFile());
public int readFromFile()
{
BufferedReader br = null;
try
{
br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\Temp\\countStorage.txt"))));
String line = br.readLine();
int count = Integer.parseInt(line);
return count;
In the readFromFile function, you read it from the file, return it, but don't keep track of it in a variable, why don't you replace the println with this inside your main:
count=f.readFromFile
I have a text file with a maximum of 4 lines to read from. Each line has a mixture of strings and integers spaced out by tabs.
I have successfully made my program read 1 line and store all the information in the appropriate spot, while also storing a new object in the array.
The problem: I can't figure out how to get it to read multiple lines while also storing a new object in the array depending on the line read.
Here is my method that takes the file and and stores an object in the array:
public void addVehicle(Vehicle Honda[]) throws FileNotFoundException
{
Scanner reader = new Scanner(file);
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length; i++)
{
if(vehicles[i] == null)
{
Honda[i] = new Vehicle();
Honda[i].readRecord(reader);
vehicles[i] = Honda[i];
reader.close();
break;
}
}
System.out.println("Vehicle Added!");
}
else
{
System.out.println("You can not add more than 4 vehicles.");
}
}
And the readRecord() method:
public void readRecord(Scanner reader)
{
while(reader.hasNextLine())
{
setMake(reader.next());
setModel(reader.next());
setYear(reader.nextInt());
setvin(reader.next());
setValue(reader.nextDouble());
setMilesDriven(reader.nextInt());
setLastOilChange(reader.nextInt());
}
reader.close();
}
If you can only successfully store one Vehicle instance, it's because your closing the reader too soon.
In addVehicle(), get rid of
reader.close();
and in readRecord(), get rid of
reader.close();
Close the reader at the end of addVehicle().
Finally fixed my problem!
public boolean addVehicle(Vehicle[] Honda) throws FileNotFoundException
{
boolean found = false;
int position = 0;
if(canAddVehicle() == true)
{
for(int i = 0; i < vehicles.length && !found; i++)
{
if(vehicles[i] == null)
{
position = i;
found = true;
}
}
Scanner reader = new Scanner(file);
while(reader.hasNext())
{
Honda[position] = new Vehicle();
Honda[position].readRecord(reader);
vehicles[position] = Honda[position];
position++;
}
reader.close();
return true;
}
return false;
}