java bufferedReader. how to read parts of a line - java

Ok now, here's my question. I wrote an algorithm to do specific things. Currently I create my processes myself in the class constructor and store them in a priority queue. However I want to be able to write a .txt file with multiple lines. Each line will represent a process with its different attributes separated by space. Here's what my .txt will look like:
P1 0 8
P2 1 4
P3 2 9
P4 3 3
END 4 9999
p1, p2... etc are the names of each process. Then the second column is the first attribute and the third column is the second attribute.
I need to be able to read each column at a time and store the value in my processes. How can I read those values and distinguish between them? (treat them as separate things)

So you want to read the file line-by-line and separate each line?
BufferReader in=new BufferedReader...
String line;
while ((line=in.readLine())!=null) {
String[] data=line.split(" ");
//now, data will be a array which contains the data
//data[0] = the first item in the line
//data[1] = the first number
//data[2] = the second number
}

Have a look at the java.util.Scanner class, it can help to read separate tokens from a Reader.
It has methods to read the next token as an integer, as a string or many other types. There are also some examples in the class Javadoc...

You got both whitespace (seperating the attributes) and new line (seperates the whole process information) as seperators.
Using a BufferedReader, you could either read a whole line (reader.readLine()) to parse one whole process information and use String.split() to seperate the attributes (edit: see answer from dyslabs).
An obviously more performant (but less intuitive) approach is to read single characters (reader.read()) and check if you either read a whitespace- or a new-line-character:
// caution: code is not tested but shows the general approach
List<ProcessInformation> processInfo = new ArrayList<>();
String pInfoStr = new String[3];
int processInfoIndex = 0;
String[] processInfoHolder = new String[3];
String processInfo = "";
int c;
while( (c = reader.read()) != -1 ) {
if (Character.isWhitespace(c)) {
processInfoHolder[processInfoIndex++] = processInfo;
processInfoStr = "";
}
else if (c == 10) { // not sure if correct codepoint for whitespace
processInfo.add(new ProcessInfo(processInfoHolder));
processInfoIndex = 0;
}
else {
processInfoStr += c;
}
}
You could even more optimize this method by using StringBuilder.

In order to be able to read a file line by line I use readLine() != null while in order to retrieve the values separated by whitespace, use the split method and store each value of a single line in an array,
here's how I implemented your example:
public static void main(String[] args) {
// TODO Auto-generated method stub
BufferedReader buffer;
FileReader fileReader;
String p1[] = new String[4];
String p2[] = new String[4];
String p3[] = new String[4];
String p4[] = new String[4];
String end[] = new String[4];
try {
fileReader = new FileReader(new File("file.txt"));
buffer = new BufferedReader(fileReader);
String line;
line = buffer.readLine();
// ============= Read the fist line =============
p1 = line.split("\\s+");
while((line = buffer.readLine()) != null) {
// ============= Read the second line =============
p2 = line.split("\\s+");
// ============= Read the third line =============
if((line = buffer.readLine()) != null) {
p3 = line.split("\\s+");
}
// ============= Read the forth line =============
if((line = buffer.readLine()) != null) {
p4 = line.split("\\s+");
}
// ============= Read the last line =============
if((line = buffer.readLine()) != null) {
end = line.split("\\s+");
}
}
fileReader.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int v1[] = new int[3];
int v2[] = new int[3];
int v3[] = new int[3];
int v4[] = new int[3];
int v_end[] = new int[3];
for (int i = 0 ; i < p1.length; i++)
System.out.print(p1[i]+ " ");
System.out.println();
for (int i = 0 ; i < p2.length; i++)
System.out.print(p2[i]+ " ");
System.out.println();
for (int i = 0 ; i < p3.length; i++)
System.out.print(p3[i]+ " ");
System.out.println();
for (int i = 0 ; i < p4.length; i++)
System.out.print(p4[i]+ " ");
System.out.println();
for (int i = 0 ; i < end.length; i++)
System.out.print(end[i]+ " ");
}

Related

Cyclically call function based on segments of input

I'm working on a class assignment. I need to read in a file containing lines of input. Every block of three lines is a structured set: The first is one polynomial, the second is another polynomial, the third is a text string that indicates the algebraic operation for the polynomial arithmetic. I've set my program up so that it reads each line into an array, and then I parse the two array indices containing integers into my polynomial term. I call the appropriate function based on the third line. My struggle is finding a way to get the process to reset after each third line. Here is the code for my main function. I thought I would use an i-loop (k-loop here) somehow, but I can't get it to work. Any insight or suggestions greatly appreciated.
Example of input:
3 2 4 5
5 7 4 6
subtract
4 3 5 1
1 2 3 4
add
Here is my code:
public static void main(String[] args) throws IOException {
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
int lines = 0;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader("Test.txt"));
String line=null;
while((line = reader.readLine()) != null) {
list.add(line);
lines++;
} // end while
} catch (FileNotFoundException e){
e.printStackTrace();
}
System.out.println("lines " + lines);
for (int k=0; k<lines; k++){
String[] stringArr = list.toArray(new String[0]);
System.out.println(stringArr[k+0]);
System.out.println(stringArr[k+1]);
System.out.println(stringArr[k+2]);
String[] nums1 = stringArr[k+0].split(" ");
String[] nums2 = stringArr[k+1].split(" ");
for (int i=0; i<nums1.length; i+= 2) {
p1.addTerm(Integer.parseInt(nums1[i]), Integer.parseInt(nums1[i+1]));
}
for (int i=0; i<nums2.length; i+= 2) {
p2.addTerm(Integer.parseInt(nums2[i]), Integer.parseInt(nums2[i+1]));
}
if (stringArr[k+2].equalsIgnoreCase("add")) {add(p1,p2);}
else if (stringArr[k+2].equalsIgnoreCase("subtract")) {subtract(p1,p2);}
else if(stringArr[k+2].equalsIgnoreCase("multiply")) {multiply(p1,p2);}
else {
System.out.println("Bad input");
}
nums1=null;
nums2=null;
}
}
Suggestion: Try something like the Scanner class? Catch the NoSuchElementException if it should run out of lines in the file.
Scanner scanner = new Scanner(new String("input"));
while(scanner.hasNextLine()) {
String lineOne = scanner.nextLine();
String lineTwo = scanner.nextLine();
String lineThree = scanner.nextLine();
calculateSomething(lineOne, lineTwo, lineThree);
}
It can be used to read strings to (space-delimited by default)
private static int[] getPolynomialFactors(String line) {
Scanner splitter = new Scanner(line);
int[] p = new int[4];
int counter=0;
while (splitter.hasNextInt()){
p[counter] = splitter.nextInt();
counter++;
}
return p;
}
With a good night's sleep, I was able to figure it out. I used a for-loop and just had to modify the incrementing of the loop counter. I nulled the pointers to the integer arrays I was using to store the integers parsed from the first two lines of the code block, which effectively reset them. Here is my updated code that works:
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Polynomial p1 = new Polynomial();
Polynomial p2 = new Polynomial();
int lines = 0;
List<String> list = new ArrayList<String>();
try {
BufferedReader reader = new BufferedReader(new FileReader("Test.txt"));
String line=null;
while((line = reader.readLine()) != null) {
list.add(line);
lines++;
} // end while
} catch (FileNotFoundException e){
e.printStackTrace();
}
System.out.println("lines " + lines);
String[] stringArr = list.toArray(new String[0]);
for (int k=0; k<lines; k+=3){
System.out.println(stringArr[k+0]);
System.out.println(stringArr[k+1]);
System.out.println(stringArr[k+2]);
String[] nums1 = stringArr[k+0].split(" ");
String[] nums2 = stringArr[k+1].split(" ");
for (int i=0; i<nums1.length; i+= 2) {
p1.addTerm(Integer.parseInt(nums1[i]), Integer.parseInt(nums1[i+1]));
}
for (int i=0; i<nums2.length; i+= 2) {
p2.addTerm(Integer.parseInt(nums2[i]), Integer.parseInt(nums2[i+1]));
}
if (stringArr[k+2].equalsIgnoreCase("add")) {add(p1,p2);}
else if (stringArr[k+2].equalsIgnoreCase("subtract")) {subtract(p1,p2);}
else if(stringArr[k+2].equalsIgnoreCase("multiply")) {multiply(p1,p2);}
else {
System.out.println("Bad input");
break;
}
nums1=null;
nums2=null;
}
}
}

How can i pass all integers i this loop and stop before the last line

this is my input
first line
5 6
3 4
2 3
2 5
1 0
word 2 2 4
i need to add all the integers to a graph but not the last line (word 1 2 4)..
i have splitted the first line (first line etc.) and put them in a arraylist.. No problem there
but then i have this for-loop
for (int i = 0; i < (amount of lines); i++) {
StringTokenizer st = new StringTokenizer(in.readLine());
graph.addEdge(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
}
i cant write in the code how many times i want it to put integers, because my code should run generally with other inputs...
How can i make it stop before the last line, i still need to be able to use the last bufferreaderline
Assuming that you always have one first line to create the graph, and a last line to do whatever. What you want to iterate over for adding Edges to the Graph are the lines between first an last.
I hope I'm guessing right.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
List<String> lines = new ArrayList<>();
/* Iterating over the whole input first*/
while((line = in.readLine()) != null) {
lines.add(line);
}
String firstLine = lines.get(0);
String lastLine = lines.get(lines.size() - 1);
StringTokenizer stok = new StringTokenizer(firstLine);
ArrayList<String> pax = new ArrayList<String>();
while(stok.hasMoreTokens()){
pax.add(stok.nextToken());
}
int v = pax.size();
Graaph graph = new Graaph(V);
/* Create the edges */
for (int i = 1; i < lines.size()-1; i++) {
StringTokenizer st = new StringTokenizer(in.readLine());
graph.addEdge(Integer.parseInt(st.nextToken()),
Integer.parseInt(st.nextToken()));
}
This assumes that your input is not empty, but I guess you can handle that.
I hope this helps.
I would just use try-catch:
ArrayList<Integer> nums = new ArrayList<Integer>();
String lastLine = "";
try {
while ((lastLine = in.readLine()) != null) {
StringTokenizer st2 = new StringTokenizer(lastLine);
graph.addEdge(Integer.parseInt(st2.nextToken()),
Integer.parseInt(st2.nextToken()));
}
}
catch (NumberFormatException e) {}
System.out.println(lastLine);

Read first character on each line in a file

I have a file in this format:
0 2 4
3 2 4
3 5 2
1 8 2
My aim is to read the first line on each file and store it in a array. So at the end I should have 0,3,3,1
I thought one approach would be, read the line until we encounter a space and save that in a array...but it would keep on reading 2 and 4 after
Is there a efficient way of doing this, my cod is shown below:
openandprint()
{
int i = 0;
try (BufferedReader br = new BufferedReader(new FileReader("final.txt")))
{
String line;
while ((line = br.readLine()) != null) {
int change2Int=Integer.parseInt(line.trim());
figures [i] = change2Int;
i++;
}
}
catch (Exception expe)
{
expe.printStackTrace();
}
}
Using a Scanner would make the code considerably cleaner:
private static openandprint() throws IOException {
int i = 0;
try (Scanner s = new Scanner("final.txt"))) {
String line;
while (s.hasNextLine()) {
int change2Int = s.nextInt();
s.nextLine(); // ignore the rest of the line
figures [i] = change2Int;
i++;
}
}
}
Try
int change2Int=Integer.parseInt((line.trim()).charAt(0)-'0');
or
int change2Int=Character.getNumericValue(line.charAt(0));
with your approch you are reading the whole line and parsing it to int which will give you NumberFormatException because of the space between the digits.
BufferedReader br = ...;
String line = null;
while ((line = br.readLine()) != null) {
String[] parts = line.split(" ");
int next = Integer.parseInt(parts[0]);
System.out.println("next: " + next);
}

In Java how to check if the next record in a file is the end?

I want to sequentially read each line of an input unsorted file into consecutive elements of the array until there are no more records in
the file or until the input size is reached, whichever occurs first. but i can't think of a way to check the next line if its the end of the file?
This is my code:
Scanner cin = new Scanner(System.in);
System.out.print("Max number of items: ");
int max = cin.nextInt();
String[] input = new String[max];
try {
BufferedReader br = new BufferedReader(new FileReader("src/ioc.txt"));
for(int i=0; i<max; i++){ //to do:check for empty record
input[i] = br.readLine();
}
}
catch (IOException e){
System.out.print(e.getMessage());
}
for(int i=0; i<input.length; i++){
System.out.println((i+1)+" "+input[i]);
}
the file has 205 lines, if I input 210 as max, the array prints with five null elements like so..
..204 Seychelles
205 Algeria
206 null
207 null
208 null
209 null
210 null
Thanks for your responses in advance!
From the docs:
public String readLine()
Returns: A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has
been reached
In other words, you should do
String aux = br.readLine();
if(aux == null)
break;
input.add(aux)
I recomend you use a variable-size array (you can pre-allocated with the requested size if reasonable). Such that you get either the expected size or the actual number of lines, and can check later.
(depending on how long your file is, you might want to look at readAllLines() too.)
Please refer this Number of lines in a file in Java and modify your for loop to take whatever is the least out of the entered max value or the no.of lines in the file.
Use List<String>
List<String> lines = new ArrayList<>(); // Growing array.
try (BufferedReader br = new BufferedReader(new FileReader("src/ioc.txt"))) {
for(;;) {
String line = br.readLine();
if (line == null) {
break;
}
lines.add(line);
}
} catch (IOException e) {
System.out.print(e.getMessage());
} // Closes automatically.
// If lines wanted as array:
String[] input = lines.toArray(new String[lines.size()]);
Using a dynamically growing ArrayList is the normal way to deal with such problem.
P.S.
FileReader will read in the current platform encoding, i.e. a local file, created locally.
You could do a null check in your first for-loop like:
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
System.out.print("Max number of items: ");
int max = cin.nextInt();
BufferedReader br = new BufferedReader(new FileReader("src/ioc.txt"));
List<String> input = new ArrayList<>();
String nextString;
int i;
for (i = 0; i < max && ((nextString = br.readline()) != null); i++) {
input.add(nextString);
}
for (int j = 0; j < i; j++) {
System.out.println((j + 1) + " " + input.get(j));
}
}
Try :
for(int i=0; i<max; i++){ //to do:check for empty record
if(br.readLine()!=null)
input[i] = br.readLine();
else
break;
}
int i=0;
for(; i<max; i++){ //to do:check for empty record
String line=br.readLine();
if(line==null){
break;
}
input[i] = line;
}
//i will contain the count of lines read. indexes 0...(i-1) represent the data.

Trying to find the nth element to the last from a list (with a file input)

Input would look like
a b c d 4
e f g h 2
where each line would be read like a list and integer representing as an index in the list
I first try to read the file line be line and store it in the list. Heres what i have
public class FileReader {
public static void main(String[] args) {
String line = null;
List<String> list = new ArrayList<String>();
try {
FileInputStream fstream = new FileInputStream("test.txt");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// File file = new File("test.txt");
// Scanner scanner = new Scanner(file);
while ((line = br.readLine()) != null) {
list.add(line);
}
System.out.println(list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Now i want to remove the white spaces from the list and store the values in char array and then i was planning on traversing that array backwards till the nth element, depending on the input for n.
String[] elements = line.trim().split("\\s");
char[] chars = new char[elements.length - 1];
int i= Integer.parseInt(elements[elements.length - 1]);
for (i = 0; i < elements.length - 1; i++)
char[i] = elements[i].charAt(i);
Someone provided me this piece of code earlier and i tried it and it throws a nullpointerexception at String[] elements.
It's because you are running until line is null here
while((line = br.readLine()) != null)
{
list.add(line);
}
And then you are trying to call .trim() on it.
Do you mean to be processing the strings in list instead?
If so try looping over you list, you are already splitting it correctly and getting the last element. All you need to do is caluclate the offset, in this case it will be the length - 1 - the last element, in you String[] elements and you can print that out.
for (int i = 0; i < list.size(); i++)
{
String currentLine = list.get(i);
String[] elements = currentLine.trim().split("\\s");
int lastElement = Integer.parseInt(elements[elements.length - 1]);
String desiredValue = elements[elements.length - 1 - lastElement];
System.out.println("desiredValue = " + desiredValue);
}
You can avoid most of the work you're doing. I don't know if your input will require much flexibility (code to that if necessary) but in your example you only have 1 digit for the index.
Just avoid all the traversing and looping entirely:
String currentLine = file.nextLine();
//Find value from last space in the string, until the end of the string (will be the number)
int index = Integer.parseInt(currentLine.substring(
currentLine.lastIndexOf(' ') + 1, currentLine.length()));
//Remove all spaces from the current line
currentLine = currentLine.replaceAll("\\s+","");
//Remove the index at the end from the string, leaving only the characters
currentLine = currentLine.substring(0, currentLine.indexOf(index + ""));
char desiredValue = currentLine.charAt(currentLine.length() - index);
System.out.println("desiredValue = " + desiredValue);
This saves a lot of adding stuff to arrays if none of that is needed later, just do it all the first time through.

Categories