OK so I have read plenty of examples on here dealing with reading in lines from a text file and splitting them up but im not quite sure I understand how to do it in my situation. I have a file that is basically separated into three columns as follows:
START 5000
FIND A
PLUS B
SAVE C
STOP
A, INT 69
B, INT -420
C, CRAZY 008484342
What I am trying to do is read in this .txt file containing the above information. I figured reading in the file line by line would be best, then splitting it into the correct columns. The problem that I am having is the fact that the 1st column is not always here. It is an optional one. If they were all filled in, im almost positive I could just use use something like
String[] array1 = myLine.split(",");
Another idea I had was to split the line based on ,'s then split the line again based on " " but im not exactly sure how to do this. Maybe somthing like
String[] array1 = myLine.split(",");
String[] array2 = array1[1].split(" ");
Also, is there any way to just read in the file and store each row into like (String, String String) then just check for ints vs strings? Maybe in a try catch? or like:
Scanner input = new Scanner(File);
while(input.hasNext()){
String str = input.next();
try{
b = Integer.parseInt(str);
}
I am not sure if this is as hard as a task as im making it but maybe so... Any help with this topic would be appreciated.
After looking over some more code, I have the following to start:
public static void main(String[] args) {
String file ="TEST.txt";
try{
FileReader input = new FileReader(file);
BufferedReader bufferReader = new BufferedReader(input);
String line;
while ((line = bufferReader.readLine()) != null) {
// Is this where I would attempt to split the lines?
System.out.println(line);
}
bufferReader.close();
}catch(Exception e){
System.out.println("Error while reading file line by line:" + e.getMessage());
}
}
}
So with this, I am successfully reading in the file and displaying the information back to the output console. Now for separating the lines... Ill be posting my work as I go, any help and or suggestions would be appreciated! Also thank you to those who have already commented with helping to split the stings, ill be attempting this now!
You can combine both expressions and only checked the array's length. e.g.:
String[] array = line.trim().split("[, ]+");
switch(array.length) {
case 2:
// do something
break;
case 3:
// do something
break;
default:
// something wrong
break;
}
The trim() in the line is for avoid empty string in the first element array.
Use split(" +") which will split on any numbers of spaces. This works because split handles regex. If you want to split on any type of whitespace you can also use split("\\s+). After you get the array check if it has 2 or 3 elements and handle it accordingly.
Well ... I don't have the time yet for a long answer. But I'd recommend you to read a little bit about regular expressions (RegEx) and how it is used in java ... I am sure this will help you with this problem and a huge amount of future problems like this ...
Try this: http://www.vogella.com/articles/JavaRegularExpressions/article.html ... of this http://docs.oracle.com/javase/tutorial/essential/regex/ ... if the first one does not help ;)
Related
I am using 'java.util.Scanner' to read and scan for keywords and want to print the previous 5 lines and next 5 lines of the encountered keyword, below is my code
ArrayList<String> keywords = new ArrayList<String>();
keywords.add("ERROR");
keywords.add("EXCEPTION");
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int count = 0;
String previousLine = null;
while(input.hasNext()){
String line = input.nextLine();
for(String keyword : keywords){
if(line.contains(keyword)){
//print prev 5 lines
system.out.println(previousLine); // this will print only last previous line ( i need last 5 previous lines)
???
//print next 5 lines
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
system.out.println(input.nextLine());
}
previousLine = line;
}
any pointers to print previous 5 lines..?
any pointers to print previous 5 lines..?
Save them in an Dequeue<String> such as a LinkedList<String> for its "First In First Out (FIFO)" behavior.
Either that or use 5 variables or an array of 5 Strings, manually move Strings from one slot or variable to another, and then print them.
If you use Dequeue/LinkedList, use the Dequeue's addFirst(...) method to add a new String to the beginning and removeLast() to remove the list's last String (if its size is > 5). Iterate through the LinkedList to get the current Strings it contains.
Other suggestions:
Your Scanner's check scanner.hasNextXXX() method should match the get method, scanner.nextXXX(). So you should check for hasNextLine() if you're going to call nextLine(). Otherwise you risk problems.
Please try to post real code here in your questions, not sort-of, will never compile code. i.e., system.out.println vs System.out.println. I know it's a little thing, but it means a lot when others try to play with your code.
Use ArrayList's contains(...) method to get rid of that for loop.
e.g.,
LinkedList<String> fivePrevLines = new LinkedList<>();
java.io.File file = new java.io.File(LOG_FILE);
Scanner input = null;
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (input.hasNextLine()) {
String line = input.nextLine();
if (keywords.contains(line)) {
System.out.println("keyword found!");
for (String prevLine : fivePrevLines) {
System.out.println(prevLine);
}
} else {
fivePrevLines.addFirst(line);
if (fivePrevLines.size() > 5) {
fivePrevLines.removeLast();
}
}
}
if (input != null) {
input.close();
}
Edit
You state in comment:
ok i ran small test program to see if the contains(...) method works ...<unreadable unformatted code>... and this returned keyword not found...!
It's all how you use it. The contains(...) method works to check if a Collection contains another object. It won't work if you feed it a huge String that may or may not use one of the Strings in the collection, but will work on the individual Strings that comprise the larger String. For example:
ArrayList<String> temp = new ArrayList<String>();
temp.add("error");
temp.add("exception");
String s = "Internal Exception: org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot get a connection, pool error Timeout waiting for idle object";
String[] tokens = s.split("[\\s\\.:,]+");
for (String token : tokens) {
if (temp.contains(token.toLowerCase())) {
System.out.println("keyword found: " + token);
} else {
System.out.println("keyword not found: " + token);
}
}
Also, you will want to avoid posting code in comments since they don't retain their formatting and are unreadable and untestable. Instead edit your original question and post a comment to alert us to the edit.
Edit 2
As per dspyz:
For stacks and queues, when there isn't any significant functionality/performance reason to use one over the other, you should default to ArrayDeque rather than LinkedList. It's generally faster, takes up less memory, and requires less garbage collection.
If your file is small (< a million lines) you are way better off just copying the lines into an ArrayList and then getting the next and previous 5 lines using random access into the array.
Sometimes the best solution is just plain brute force.
Your code is going to get tricky if you have two keyword hits inside your +-5 line window. Let's say you have hits two lines apart. Do you dump two 10-line windows? One 12-line window?
Random access will make implementing this stuff way easier.
i need your advise in order to do something ... i want to take the user's input line as i already do in my program with scanner ... but i want to split each command(word) to tokens .... i do not know how to do that , till now i was playing with substring but if the users for example press twice the space-bar button everything is wrong !!!!!
For example :
Please insert a command : I am 20 years old
with substring or .split(" ") , it runs but think about having :
Please insert a command : I am 20 years old
That is why i need your advice .... The question is how can i split the user's input with tokens.
Well, you need to normalize you string line before splitting it to tokens. A simplest way is to remove repeated whitespace characters:
line = line.replaceAll("\\s+", " ");
(this will also replace all tabs to a single " ").
Use the StringTokenizer class. From the API :
"[It] allows an application to break a string into tokens... A
StringTokenizer object internally maintains a current position within
the string to be tokenized."
The following sample code from the API will give you an idea:
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
It produces the following result:
this
is
a
test
Okay, so the code that I have made is going to ask you for to insert a command, it is then going to take your command and then split it around any number of spaces (due to the Regex). It then saves these words, numbers, speech marks etc. as tokens. You can then manipulate each word in the for loop.
import java.util.Scanner;
public class CommandReaderProgram{
public static void main(String[] args){
Scanner userInput = new Scanner(System.in);
System.out.println("Please insert a command:");
String temp = userInput.nextLine();
while(temp != null){
String [] tokens = temp.split("\\s+");
for(String word : tokens){
System.out.print(word);
System.out.print(" ");
}
break;
}
System.out.print("\n");
}
}
To test that each word, number and speech mark has actually been saved as a token, change the character in the System.out.print(" "); code to anything. e.g System.out.print(""); or
System.out.print("abcdefg"); and it will put this data between each token, to prove that the tokens are indeed separate.
Unfortunately I am unable to call the token array outside of the for loop at the moment, but will let you know when I figure it out.
I'd like to hear what type of program you are trying to make as I think we are both trying to make something very similar.
Hope this is what you are looking for.
Regards.
Let's say I got a textfile.txt that I want to read from. This is the text in the file:
23:years:old
15:years:young
Using the useDelimiter method, how can I tell my program that : and newlines are delimiters? Putting the text in one line and using useDelimter(":"); works. The problem is when I got several lines of text.
Scanner input = new Scanner(new File("textfile.txt));
input.useDelimiter(:);
while(data.hasNextLine()) {
int age = input.nextInt();
String something = input.next();
String somethingelse = input.next();
}
Using this code I will get an inputMisMatch error.
Try
scanner.useDelimiter("[:]+");
The complete code is
Scanner scanner = new Scanner(new File("C:/temp/text.txt"));
scanner.useDelimiter("[:]+");
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
The output is
23
years
old
15
years
young
Use this code
Scanner input;
String tokenizer[];
try {
input = new Scanner(new File("D:\\textfile.txt"));
input.useDelimiter("\\n");
while(input.hasNextLine()) {
tokenizer = input.next().split(":");
System.out.println(tokenizer[0]+" |"+tokenizer[1]+" | "+tokenizer[2]);
}
}catch(Exception e){}
It will give you output like
23 |years | old
15 |years | young
You have two ways to do this:
Concatenate the string to make it one line.
delimit "newline" first, then delimit ":" each return string token.
If all you want is to get everything split up all at once then I guess you can use
useDelimiter(":\\n")
That should split on both : and newspace but it is not the most efficient way of processing data, especially if each line of text is set out in the same format and represents a complete entry. If that is the case then my suggestion would be to only split on a new line to begin with, like this;
s.useDelimiter("\\n");
while(s.hasNext()){
String[] result = s.next.split(":");
//do whatever you need to with the data and store it somewhere
}
This will allow you to process the data line by line and will also split it at the required places. However if you do plan on going through line by line I recommend you look at BufferedReader as it has a readLine() function that makes things a lot easier.
As long as all the lines have all three fields you can just use input.useDelimiter(":\n");
you probably wants to create a delimiter pattern which includes both ':' and newline
I didn't test it, but [\s|:]+ is a regular expression that matches one or more whitespace characters, and also ':'.
Try put:
input.useDelimiter("[\\s|:]+");
I am trying to display statistics from a simple text file using arrays in Java. I know what I am supposed to do, but I don't really how how to code it. So can anybody show me a sample code on how to do it.
So let's say the text file is called gameranking.txt, that contains the following information (This is a simple txt file to use as an example):
Game Event, 1st place, second place, third place, fourth place
World of Warcraft, John, Michael, Bill, Chris
Call of Duty, Michael, Chris, John, Bill
League of Legends, John, Chris, Bill, Michael.
My goal is to display stats such as how many first places, second places.. each individual won in a table like the following
Placement First place, second, third, fourth
John 2 0 1 0
Chris 0 2 0 1
etc...
My thought:
First, I would read the gameranking.txt and stores it to "input". Then I can use the while loop to read each line and store each line into a string called "line", afterward, I would use the array method "split" to pull out each string and store them into individual array. Afterward, I would count which placement each individual won and display them into a neat table using printf.
My first problem is I don't know how to create the arrays for this data. Do I first need to read through the file and see how many strings are in each row and column, then create the array table accordingly? Or can I store each string in an array as I read them?
The pseudocode that I have right now is the following.
Count how many rows are there and store it in row
Count how many column are there and store it in column
Create an array
String [] [] gameranking = new String [row] [column]
Next read the text file and store the info into the arrays
using:
while (input.hasNextLine) {
String line = input.nextLine();
while (line.hasNext()) {
Use line.split to pull out each string
first string = event and store it into the array
second string = first place
third string =......
Somewhere in the code, I need to count the placement....
Can somebody please show me how I should go about doing this?
I am not going to write the full program, but I will try to tackle each question and give you a simple suggestion:
Reading the initial file, you can get each line and store it in a string using a BufferedReader (or if you like, use a LineNumberReader)
BufferedReader br = new BufferedReader(new FileReader(file));
String strLine;
while ((strLine = br.readLine()) != null) {
......Do stuff....
}
At that point, in the while loop you will go through the string (since it comma delimited, you can use that to seperate each section). for each substring you can
a) compare it with first, second, third, fourth to get placement.
b) if its not any of those, then it could either be a game name or a user name
You can figure that out by position or nth substring (ie if this is the 5th substring, its likely to be the first game name. since you have 4 players, the next game name will be the 10th substring, etc.). Do note, I ignored "Game event" as that's not part of the pattern. You can use split to do this or a number of other options, rather than try to explain that I will give you a link to a tutorial I found:
http://pages.cs.wisc.edu/~hasti/cs302/examples/Parsing/parseString.html
As for tabulating results, Basically you can get an int array for each player which keeps track of their 1st, 2nd, 3rd, awards etc.
int[] Bob = new int[4]; //where 0 denotes # of 1st awards, etc.
int[] Jane = new int[4]; //where 0 denotes # of 1st awards, etc.
Showing the table is a matter of organizing the data and using a JTable in a GUI:
http://docs.oracle.com/javase/tutorial/uiswing/components/table.html
Alrighty...Here is what I wrote up, I am sure there is a cleaner and faster way, but this should give you an idea:
String[] Contestants = {"Bob","Bill","Chris","John","Michael"};
int[][] contPlace=new int[Contestants.length][4];
String file = "test.txt";
public FileParsing() throws Exception {
Arrays.fill(contPlace[0], 0);
Arrays.fill(contPlace[1], 0);
Arrays.fill(contPlace[2], 0);
Arrays.fill(contPlace[3], 0);
BufferedReader br = new BufferedReader(new FileReader(file));
String strLine;
while((strLine=br.readLine())!=null){
String[] line = strLine.split(",");
System.out.println(line[0]+"/"+line[1]+"/"+line[2]+"/"+line[3]+"/"+line[4]);
if(line[0].equals("Game Event")){
//line[1]==1st place;
//line[2]==2nd place;
//line[3]==3rd place;
}else{//we know we are on a game line, so we can just pick the names
for(int i=0;i<line.length;i++){
for(int j=0;j<Contestants.length;j++){
if(line[i].trim().equals(Contestants[j])){
System.out.println("j="+j+"i="+i+Contestants[j]);
contPlace[j][i-1]++; //i-1 because 1st substring is the game name
}
}
}
}
}
//Now how to get contestants out of the 2d array
System.out.println("Placement First Second Third Fourth");
System.out.println(Contestants[0]+" "+contPlace[0][0]+" "+contPlace[0][1]+" "+contPlace[0][2]+" "+contPlace[0][3]);
System.out.println(Contestants[1]+" "+contPlace[1][0]+" "+contPlace[1][1]+" "+contPlace[1][2]+" "+contPlace[1][3]);
System.out.println(Contestants[2]+" "+contPlace[2][0]+" "+contPlace[2][1]+" "+contPlace[2][2]+" "+contPlace[2][3]);
System.out.println(Contestants[3]+" "+contPlace[3][0]+" "+contPlace[3][1]+" "+contPlace[3][2]+" "+contPlace[3][3]);
System.out.println(Contestants[4]+" "+contPlace[4][0]+" "+contPlace[4][1]+" "+contPlace[4][2]+" "+contPlace[4][3]);
}
If you need to populate the contestants array or keep track of the games, you will have to insert appropriate code. Also note, using this 2-d array method is probably not best if you want to do anything other than display them. You should be able to take my code, add a main, and see it run.
Since it's a text file, use Scanner class.
It can be customized so that you can read the contents line-by-line, word-by-word, or customized delimiter.
The readfromfile method reads a plain text file one line at a time.
public static void readfromfile(String fileName) {
try {
Scanner scanner = new Scanner(new File(fileName));
scanner.useDelimiter(",");
System.out.println(scanner.next()); //instead of printing, take each word and store them in string array
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
This will get you started.
I have college project where i have to read the first word of every line from text file which looks as follow:
23123123213 Samuel classA
23423423423 Gina classC
23423423423 John classD
The text file will be updated with through 3 JTextField which i am able to figure out.
but now i have to populate the JCombobox with first word(23123123213,23423423423 and 23423423423) of all the lines.
I am new to java, i dont even have hint of how about doing it.
I know how to read and write to text files.
Please could someone help me do this?
The code so far i came up with is as follows:
import java.io.*;
public class FileRead
{
public static void main(String args[])
{
try{
// Open the file that is the first
// command line parameter
FileInputStream fstream = new FileInputStream("RokFile.txt");
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
String[] delims = strLine.split(" ");
String first = delims[0];
System.out.println("First word: "+first);
}
//Close the input stream
in.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
}
With u guys help I was successfully able to extract the first string from each line
but now how could i populate it in Jcombobox, I mean should i save it somewhere first?
Thanks in Advance
I'm not "down" with Java, however I can give you a few pointers:
You can read files, and presumably can read a line.
Each line is (presumably) separated with spaces so what you need to look up is a String.split function
Once you've split a string you will be able to use array index 0 to get the information you need.
Then it's just a case of adding split_string[0] to the JComboBox.
The documents are a great help:
String
JComboBox
You can get the first word using String.split(), or by using indexOf and substring.
There is a tutorial about JComboBox.
The Java Swing classes are based on Model/View, so you have to fill the strings into the Model of the JCombobox.
EDIT: In response to your edit, suppose you have retrieved the values. Then you can indeed save them to a specific data structure. It would be preferable to make the code that retrieves those values into a separate method. The values returned from that method (in, for example, a List<String>) can then be put into the JComboBox.
If you know how to read lines from a text file you can split each line by a delimiter, using the String.split function. In that case you get an array, with which you can get the first string by a normal array indexer, the [] operator that is.
String hello = "Hello world";
String[] delims = hello.split(" ");
String first = delims[0];
To answer your edit, you populate the JComboBox using one of its constructors, for instance the one that takes an Object array, or using the JComboBox.addItem(Object) function.
The latter has an example. Regarding the one with the constructor you can either build an array of objects yourself, or use an arraylist to which you add all your elements and then get an array using the ArrayList.toArray() function.