So I am trying to extract a piece of code from a txtfile ,the start of the piece being indicated by "# EMPIRES" and the end being indicated by another string starting with a '#'. My program however never finds the start of the piece and keeps on going until it reaches the end of the file.
To try and find out what the problem was I tried first to print every line that it finds.
And here I encountered another problem. My code already stops finding new lines,long before
"# EMPIRES" is even reached.
public String getEmpirestxt(String fileName) {
Scanner sc;
try {
sc = new Scanner(new File(fileName));
String currentLine = sc.nextLine();
StringBuilder empiresText = new StringBuilder(currentLine);
while (!currentLine.startsWith("# EMPIRES")) {
currentLine = sc.nextLine();
System.out.println(currentLine);
}
currentLine = sc.nextLine();
while (sc.hasNextLine() && currentLine.charAt(0)!='#') {
empiresText.append("\n").append(sc.nextLine());
}
return empiresText.toString();
} catch (FileNotFoundException ex) {
System.out.println("Landed_Titles.txt not found.");
}
return null;
}
The textfile itself :
https://www.wetransfer.com/downloads/a1093792d5ac54b6ccce04afecb9357f20140402095042/505fca
Here is my solution to your problem. I used newBufferedReader instead of the Scanner to read the file. This example works with Java 7.
public String getEmpirestxt2(String fileName) {
Charset charset = Charset.forName("ISO-8859-1");
Path filePath = Paths.get(fileName);
try (BufferedReader reader = Files.newBufferedReader(filePath, charset)) {
String line = null;
// find the start of the piece
while ((line = reader.readLine()) != null && !line.equals(START)) {
}
System.out.println("START: " + line);
// getting the piece
StringBuilder sb = new StringBuilder();
while ((line = reader.readLine()) != null && !line.startsWith(END)) {
sb.append(line);
}
System.out.println("END: " + line);
return sb.toString();
} catch (IOException x) {
System.err.format("IOException: %s%n", x);
}
return null;
}
The constants in the method are:
private static final String START = "# EMPIRES";
private static final String END = "#";
I tested it with your file and it works fine. It also prints the starting and end points of the required piece:
START: # EMPIRES
END: # color={ 144 80 60 }
String currentLine = sc.nextLine();
you are starting reading from the next Line.
The condition:
while (sc.hasNextLine() && currentLine.charAt(0)!='#')
may terminate even if the file has more lines to read, because of the second predicate. If currentLine.charAt(0)!='#' is fales, the while loop ends. This does not mean there are no more lines to read.
In your second while loop you never set currentLine
This part:
currentLine = sc.nextLine();
while (sc.hasNextLine() && currentLine.charAt(0)!='#') {
empiresText.append("\n").append(sc.nextLine());
}
should be:
do{
currentLine=sc.nextLine();
empiresText.append("\n").append(sc.nextLine());
}while(sc.hasNextLine() && currentLine.charAt(0)!='#');
Otherwise the line right after # EMPIRES won't be read and the code while loop will never stop because the currentLine is not getting updated.
Append currentLine instead of sc.nextLine() in the second while loop :
while (sc.hasNextLine() && currentLine.charAt(0) != '#') {
empiresText.append("\n").append(currentLine);
currentLine = sc.nextLine();
}
Otherwise you can use a single loop like below :
while (sc.hasNextLine()){
if(sc.nextLine().startsWith("# EMPIRES")){
currentLine = sc.nextLine();
while (sc.hasNextLine() && currentLine.charAt(0) != '#') {
empiresText.append("\n").append(currentLine);
currentLine = sc.nextLine();
}
}
}
Related
I want to read the file and add each entry to an arraylist on a date. But the date should also be included.
File Example:
15.09.2002 Hello, this is the first entry.
\t this line, I also need in the first entry.
\t this line, I also need in the first entry.
\t this line, I also need in the first entry.
17.10.2020 And this ist the next entry
I tried this. But the Reader reads only the first Line
public class versuch1 {
public static void main(String[] args) {
ArrayList<String> liste = new ArrayList<String>();
String lastLine = "";
String str_all = "";
String currLine = "";
try {
FileReader fstream = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fstream);
while ((currLine = br.readLine()) != null) {
Pattern p = Pattern
.compile("[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2} [0-2]?[0-9]:[0-6]?[0-9]:[0-5]");
Matcher m = p.matcher(currLine);
if (m.find() == true) {
lastLine = currLine;
liste.add(lastLine);
} else if (m.find() == false) {
str_all = currLine + " " + lastLine;
liste.set((liste.indexOf(currLine)), str_all);
}
}
br.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
System.out.print(liste.get(0) + " "+liste.get(1);
}
}
I have solved my problem :)
public class versuch1 {
public static void main(String[] args) {
ArrayList<String> liste = new ArrayList<String>();
String lastLine = "";
String currLine = "";
String str_all = "";
try {
FileReader fstream = new FileReader("test.txt");
BufferedReader br = new BufferedReader(fstream);
currLine = br.readLine();
while (currLine != null) {
Pattern p = Pattern
.compile("[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2} [0-2]?[0-9]:[0-6]?[0-9]:[0-5]");
Matcher m = p.matcher(currLine);
if (m.find() == true) {
liste.add(currLine);
lastLine = currLine;
} else if (m.find() == false) {
liste.set((liste.size() - 1), (str_all));
lastLine = str_all;
}
currLine = br.readLine();
str_all = lastLine + currLine;
}
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
System.out.print(liste.get(1) + " ");
}
}
While reading the lines, keep a "current entry".
If the line read begins with a date, then it belongs to a new entry. In this case add the current entry to the list of entries and create a new current entry consisting of the read line.
If the line did not begin with a date, just add it to the current entry.
For this to work, you need to read the first line into the current entry before the loop. And after the loop you need to add the current entry to the list of entries. This in turn only works if there is at least one line and the first line begins with a date. So handle the special case of no lines specially (use if-else). And report an error if the first line does not begin with a date.
Happy coding.
I want to extract the first String in a file using the delimiter ",".
Why does this code generate a number of lines greater than one?
public static void main(String[] args) {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("irisAfter.txt"));
String read = null;
while ((read = in.readLine()) != null) {
read = in.readLine();
String[] splited = read.split(",");
for (int i =0; i<splited.length;i++) {
System.out.println(splited[0]);
}
}
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) { e.printStackTrace(); }
}
}
You are printing inside a loop. That's why it is printing multiple times (if that's what you're asking).
String[] splited = read.split(",");
System.out.println(splited[0]);
will just do
EDIT: As Abishek also mentioned, don't read = in.readLine(); again inside your while loop since by doing so you are skipping a line.
while ((read = in.readLine()) != null) {
String[] splited = read.split(",");
System.out.println(splited[0]);
}
What do you mean by number of lines superior to the original ones
If you are using splited[0], why are you keeping inside a loop. It will always get you same string
Not sure why your code works that way but you might try Scanner with a delimeter. Try:
Scanner sc = new Scanner( new File("myNumbers")).useDelimiter(",");
String firstString = sc.next();
/// check for null..
You read in every line from "irisAfter.txt", then split each line on "," into multiple elements, then print out the first element of that line on its own line as many times as there are elements in the line. Multiple lines*multiple elements per line = more lines in output than in input.
Change
for (int i =0; i<splited.length;i++) {
System.out.println(splited[0]);
}
to
if (splited.length > 0)
{
System.out.println(splited[0]);
}
That way you print out the first element of every line on its own line only one time and only if there actually is a first element.
You are also skipping every other line. If you don't want to do that, remove the line
read = in.readLine();
just below
while ((read = in.readLine()) != null) {.
(You are now reading in a line and then reading in the next line, discarding the first read in line. Then you process that second line, after which the loop starts again, you read in the third line, then read in the fourth line, discarding the third, etc. etc.)
if you modify your code like this, you should get the result you expect.
public static void main(String[] args) {
BufferedReader in = null;
try {
String[] splited;
in = new BufferedReader(new FileReader("irisAfter.txt"));
String read = null;
while ((read = in.readLine()) != null) {
read = in.readLine();
splited = read.split(",");
}
System.out.println(splited[0]);
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) {
}
}
}
the following code will only read the first line of a text file and it will stop there. I've been experimenting with loops but i cannot get it to successfully update the line until there are no more lines in the file. can anyone help? thanks
public void readFile(){
try {
BufferedReader in = new BufferedReader(new FileReader("test1.txt"));
words = new ArrayList<Word>();
int lineNum = 1; // we read first line in start
// delimeters of line in this example only "space"
char [] parse = {' '};
String delims = new String(parse);
String line = in.readLine();
String [] lineWords = line.split(delims);
// split the words and create word object
for (int i = 0; i < lineWords.length; i++) {
Word w = new Word(lineWords[i]);
words.add(w);
}
lineNum++; // pass the next line
line = in.readLine();
in.close();
} catch (IOException e) {
}
}
Basically, you want to keep reading until you run out of lines, at which time BufferedReader will return null
char[] parse = {' '};
String delims = new String(parse);
String line = null;
while ((line = in.readLine()) != null) {
String[] lineWords = line.split(delims);
// split the words and create word object
for (int i = 0; i < lineWords.length; i++) {
Word w = new Word(lineWords[i]);
words.add(w);
}
lineNum++; // pass the next line
}
You should be managing your resources better, if you open it, you should make all reasonable attempts to close. Currently, if your code fails for some reason, the in.close line will never be called. Also, you shouldn't ignore exceptions
Luckily, in Java 8, this is easy to manage...
try (BufferedReader in = new BufferedReader(new FileReader("test1.txt"))) {
//...
} catch (IOException e) {
e.printStackTrace();
}
Take a closer look at Basic I/O, The try-with-resources Statement and BufferedReader JavaDocs, especially BufferedReader#readLine
You may also want to take a look at LineNumberReader ;)
while((line = in.readLine()) != null){
//process line
}
This nested statement reads a line from the BufferedReader and stores it in line. At the end of the file, readLine() will return null and stop the loop.
What I'm trying to do is, load a Text file, then take the values from each line and assign them to a variable in my program. Every two lines, I will insert them into a LinkedHashMap (As a pair)
The problem with a buffered reader is, all I can seem to do is, read one line at a time.
Here is my current code:
public static void receiver(String firstArg) {// Receives
// Input
// File
String cipherText;
String key;
String inFile = new File(firstArg).getAbsolutePath();
Path file = new File(inFile).toPath();
// File in = new File(inFile);
try (InputStream in = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(
new InputStreamReader(in))) {
String line = null;
while ((line = reader.readLine()) != null) {
// System.out.println(line);
String[] arrayLine = line.split("\n"); // here you are
// splitting
// with whitespace
cipherText = arrayLine[0];
// key = arrayLine[1];
System.out.println(arrayLine[0] + " " + arrayLine[1]);
cipherKeyPairs.put(arrayLine[0], arrayLine[1]);
}
} catch (IOException x) {
System.err.println(x);
}
The problem is, it can't find the arrayLine[1] (for obvious reasons). I need it to read two lines at a time without the array going out of bounds.
Any idea how to do this, so that I can store them into my LinkedHashMap, two lines at a time as separate values.
You can overcome this issue by inserting in the List every 2 lines reading.
A description for this code is that: "Bold is the true case"
Read the first line (count is 0)
If (secondLine is false) ==> Save the line to CipherText variable, make secondLine = true
Else If (secondLine is true) ==> Add to list (CipherText, line), make secondLine = false
Read the second line (count is 1)
If (secondLine is false) ==> Save the line to CipherText variable, make secondLine = true
Else If (secondLine is true) ==> Add to list (CipherText, line), make secondLine = false
String cipherText;
boolean secondLine = false;
String inFile = new File(firstArg).getAbsolutePath();
Path file = new File(inFile).toPath();
try {
InputStream in = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String line = null;
while ((line = reader.readLine()) != null) {
if (!secondLine) //first line reading
{
cipherText = line;
secondLine = true;
}
else if (secondLine) //second line reading
{
cipherKeyPairs.put(cipherText, line);
secondLine = false;
}
}
} catch (IOException x) {
System.err.println(x);
}
See if this works for you. I just edited your code. it might not be the best answer.
public static void receiver(String firstArg) {// Receives
// Input
// File
String cipherText;
String key;
String inFile = new File(firstArg).getAbsolutePath();
Path file = new File(inFile).toPath();
// File in = new File(inFile);
try (InputStream in = Files.newInputStream(file);
BufferedReader reader = new BufferedReader(
new InputStreamReader(in))) {
String line = null;
List<String> lines = new ArrayList();
while ((line = reader.readLine()) != null) {
lines.add(line);//trim line first though and check for empty string
}
for(int i=1;i<lines.size();i++){
cipherText = arrayLine[i];
// key = arrayLine[1];
System.out.println(arrayLine[i] + " " + arrayLine[i-1]);
cipherKeyPairs.put(arrayLine[i-1], arrayLine[i]);
}
} catch (IOException x) {
System.err.println(x);
}
}
Okay, I tried everything but I can't find answer. My data reader skips empty next line while reading from a txt file.
It is supposed to strip all the comments from the txt file and print rest of the data as it is. My reader does strip the comments & prints the data but it skips the empty new lines..
MyDataReader.java
public String readLine()
{
String buf = new String();
String readStr = new String();
int end = 0;
int done = 0;
try
{
// checks if line extraction is done and marker has non null value
while (done != 1 && marker != null)
{
readStr = theReader.readLine(); // Reads the line from standard input
if (readStr != null)
{
/* If the first character of line isnt marker */
if (readStr.length() > 0)
{
if (!readStr.substring(0, 1).equalsIgnoreCase(marker))
{
end = readStr.indexOf(marker); // checks if marker exists in the string or not
if (end > 0)
buf = readStr.substring(0, end);
else
buf = readStr;
done = 1; // String extraction is done
}
}
}
else
{
buf = null;
done = 1;
}
}
}
// catches the exception
catch (Exception e)
{
buf = null;
System.out.println(e);
}
return buf;
}
TestMyDataReader.java
String myStr = new String();
myStr = _mdr.readLine();
while (myStr != null)
{
//System.out.println("Original String : " + myStr);
System.out.println(myStr);
myStr = _mdr.readLine();
}
if (readStr.length() > 0)
That's the line of code that is skipping empty lines.
lots of issues in this code, but the main problem that you are dealing with is that new lines are not included in the readLine result. Thus, your if statement is not true (the line is in fact empty
Your reader won't include the newline characer in readStr, so reading in the line "\n" will make readStr be "", and
readStr.length() > 0
Will evaluate to false, thus skipping that line.