Exception read data from file while split character "|" - java

public void loadDataFromFile(ArrayList<Book> list, String fileName) {
File f = new File(fileName);
try {
Scanner sc = new Scanner(f);
while (sc.hasNext()) {
String perLine = sc.nextLine(); //get date per line
String txt[] = perLine.split("|");
list.add(new Book(txt[0], txt[1], Integer.parseInt(txt[2]), Double.parseDouble(txt[3])));
}
} catch (FileNotFoundException ex) {
System.out.println(ex.getMessage());
}
}
My function read data from file and add data to arraylist. But when I run this function, it have bug like this picture
My file is book.txt and data of this file is
A2|Hoa|22|50.3. If i try split at character "|", it will have bug like this picture. But if i change data of file to A2 Hoa 22 50.3 and split at " " it working.

In java String split() method work's with regex as argument since '|' is special character in regex you need to escape it with \\ as folowing perLine.split("\\|");

Related

How CSV parsing can be utilized - JAVA

I am given a file that will read the following:
"String",int,int
"String",int,int
"String",int,int
...
Given an unknown number of variables, a while (scanner.hasNextLine()) can solve to the number of entries. My goal is to take these three pieces of data and store them into a Node. I am using the method BinaryTree.addNode(String, int, int) for this. My issue comes to when I am trying to read in the data. I am trying to remove the commas within the document and then attempting to re-read the data using the following:
Scanner firstpass = new Scanner(file);
String input = firstpass.nextLine().replaceAll(",", "");
Scanner secondpass = new Scanner(input);
String variable1 = secondpass.next();
int variable2 = secondpass.nextInt();
int variable3 = secondpass.nextInt();
This however is a very innefective way of going about this.
UPDATED
The compiling errors can be fixed with the following:
try {
Scanner scanner1 = new Scanner(file);
while (scanner1.hasNextLine()) {
String inventory = scanner1.nextLine().replaceAll(",", " ");
Scanner scanner2 = new Scanner(inventory);
while (scanner2.hasNext()){
String i = scanner2.next();
System.out.print(i);
}
scanner2.close();
}
scanner1.close();
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
which gives me the output:
"String"intint"String"intint"String"intint...
So I know I am on the right track. However any (spaces) within the "String" variable are removed. So they would output "SomeString" instead of "Some String". Also I still don't know how to remove the "" from the strings.
The format you've shown matches the CSV (Comma-Separated Values) format, so your best option is to use a CSV parser, e.g. Apache Commons CSV ™.
If you don't want to add a third-party library, you could use Regular Expression to parse the line.
Reading lines from a file should not be done with a Scanner. Use a BufferedReader instead. See Scanner vs. BufferedReader.
try (BufferedReader in = new BufferedReader(new FileReader(file))) {
Pattern p = Pattern.compile("\"(.*?)\",(-?\\d+),(-?\\d+)");
for (String line; (line = in.readLine()) != null; ) {
Matcher m = p.matcher(line);
if (! m.matches())
throw new IOException("Invalid line: " + line);
String value1 = m.group(1);
int value2 = Integer.parseInt(m.group(2));
int value3 = Integer.parseInt(m.group(3));
// use values here
}
} catch (IOException | NumberFormatException ex) {
ex.printStackTrace();
}
Note that this will not work if the string contains escaped characters, e.g. if it contains embedded double-quotes. For that, you should use a parser library.
The code above will correctly handle embedded spaces and commas.
I would instead of using
String input = firstpass.nextLine().replaceAll(",", "");
Scanner secondpass = new Scanner(input);
String variable1 = secondpass.next();
int variable2 = secondpass.nextInt();
int variable3 = secondpass.nextInt();
Use the following approach
String line = firstpass.nextLine();
String[] temp = line.split(",");
String variable1 = temp[0];
int variable2 = Integer.parseInt(temp[1]);
int variable3 = Integer.parseInt(temp[2]);

Part of string before a colon and then the part after the colon using a scanner

Like the title says is it possible to read part of a String before a colon and then the rest of the String after the colon using a scanner?
If you have a String:
"AA:BigHouseOnTheBeach"
is it possible for me to store the first part "AA" in a separate String and "BigHouseOnTheBeach" in a second separate String?
Here's my code:
public NumberPlates() {
// opg 2a) initialiser districtMap
districtMap = new HashMap<String, String>();
readFile();
}
public void readFile() {
file = new File("src/opg2_numberplates/Nummerplader.txt");
try {
Scanner reader = new Scanner(file);
if (reader.hasNext()) {
kb = reader.next();
pk = reader.next();
districtMap.put(kb, pk);
}
} catch (NullPointerException ex) {
System.out.println("Null pointer");
} catch (FileNotFoundException ex) {
System.out.println("File not found");
}
}
At the moment, it puts "AA:BigHouseOnTheBeach" and "AB:SmallHouseOnTheBeach" into my map as key and value. I want to put "AA" as key and "BigHouseOnTheBeach" as value.
You can use setDelimiter(String regex) method of Scanner:
Scanner scan = new Scanner("Hello: There!");
scan.useDelimiter(":");
System.out.println(scan.next());
System.out.println(scan.next());
Output:
"Hello"
" There!"
If you don't want the second string to include the space after the ":", change to:
scan.useDelimiter(":\\s*");
You can use String split method to split the string based on the delimiter. Following is the code.
if (reader.hasNext()) {
String input = reader.next();
String[] parts = input.split(":");
kb = parts[0];
pk = parts[1];
districtMap.put(kb, pk);
}

Processing text files and hyphenating strings line by line in Java

I have a .txt file with 8,000 rows in a single column. Each line contains either an alphanumeric or a number like this:
0219381A
10101298
32192017
1720291C
04041009
I'd like to read this file, insert a 0 (zero) before each beginning digit, a hyphen in between digits 3 and 4, and then remove the remaining digits to an output file like this:
002-19
010-10
032-19
017-20
004-04
I'm able to read from and write to a file or insert a hyphen when done separately but can't get the pieces working together:
public static void main(String[] args) throws FileNotFoundException{
// TODO Auto-generated method stub
Scanner in = new Scanner(new File("file.txt"));
PrintWriter out = new PrintWriter("file1.txt");
while(in.hasNextLine())
{
StringBuilder builder = new StringBuilder(in.nextLine());
builder.insert(0, "0");
builder.insert(3, "-");
String hyph = builder.toString();
out.printf(hyph);
}
in.close();
out.close();
How can I get these pieces working together/is there another approach?
try this
while (in.hasNextLine()) {
String line = in.nextLine();
if (!line.isEmpty()) {
line = "0" + line.substring(0, 2) + "-" + line.substring(2, 4);
}
out.println(line);
}
You code looks fine. If you make this changes, you should be good i feel :
StringBuilder builder = new StringBuilder(in.nextLine().substring(0,4));

reading from text file to string array

So I can search for a string in my text file, however, I wanted to sort data within this ArrayList and implement an algorithm. Is it possible to read from a text file and the values [Strings] within the text file be stored in a String[] Array.
Also is it possible to separate the Strings? So instead of my Array having:
[Alice was beginning to get very tired of sitting by her sister on the, bank, and of having nothing to do:]
is it possible to an array as:
["Alice", "was" "beginning" "to" "get"...]
.
public static void main(String[]args) throws IOException
{
Scanner scan = new Scanner(System.in);
String stringSearch = scan.nextLine();
BufferedReader reader = new BufferedReader(new FileReader("File1.txt"));
List<String> words = new ArrayList<String>();
String line;
while ((line = reader.readLine()) != null) {
words.add(line);
}
for(String sLine : words)
{
if (sLine.contains(stringSearch))
{
int index = words.indexOf(sLine);
System.out.println("Got a match at line " + index);
}
}
//Collections.sort(words);
//for (String str: words)
// System.out.println(str);
int size = words.size();
System.out.println("There are " + size + " Lines of text in this text file.");
reader.close();
System.out.println(words);
}
To split a line into an array of words, use this:
String words = sentence.split("[^\\w']+");
The regex [^\w'] means "not a word char or an apostrophe"
This will capture words with embedded apostrophes like "can't" and skip over all punctuation.
Edit:
A comment has raised the edge case of parsing a quoted word such as 'this' as this.
Here's the solution for that - you have to first remove wrapping quotes:
String[] words = input.replaceAll("(^|\\s)'([\\w']+)'(\\s|$)", "$1$2$3").split("[^\\w']+");
Here's some test code with edge and corner cases:
public static void main(String[] args) throws Exception {
String input = "'I', ie \"me\", can't extract 'can't' or 'can't'";
String[] words = input.replaceAll("(^|[^\\w'])'([\\w']+)'([^\\w']|$)", "$1$2$3").split("[^\\w']+");
System.out.println(Arrays.toString(words));
}
Output:
[I, ie, me, can't, extract, can't, or, can't]
Also is it possible to separate the Strings?
Yes, You can split string by using this for white spaces.
String[] strSplit;
String str = "This is test for split";
strSplit = str.split("[\\s,;!?\"]+");
See String API
Moreover you can also read a text file word by word.
Scanner scan = null;
try {
scan = new Scanner(new BufferedReader(new FileReader("Your File Path")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while(scan.hasNext()){
System.out.println( scan.next() );
}
See Scanner API

how do I extract Name and Value from a line of text while reading from a file using Java?

A file name will be passed in from standard in. I want to open it, read it, and create some information based off the text in the file.
For example, if this is a line in the file:
Hristo 3
... then I want to create a Member() named Hristo with a value of 3. So I want to pull out a String for the name and an int for the value. The name and the value are separated by some unknown number of tabs and spaces which I need to ignore. Could I just read the line, use .trim() to get rid of whitespace, and the last character would be the value?
I have not shown the class Member() for simplicity's sake. This is what I have so far:
public static void main(String[] args) {
int numMembers = 0;
ArrayList<Member> veteranMembers = new ArrayList<Member>();
File file = new File(args[0]);
FileReader fr;
BufferedReader br;
// attempt to open and read file
try {
fr = new FileReader(file);
br = new BufferedReader(fr);
String line;
// read file
while ((line = br.readLine()) != null) {
// extract name and value from line
... ? ...
// create member
// initialize name and value
Member member = new Member();
veteranMembers.add(member);
}
br.close();
} catch (FileNotFoundException e1) {
// Unable to find file.
e1.printStackTrace();
} catch (IOException e) {
// Unable to read line.
e.printStackTrace();
}
}
How would I parse that line of text?
Thanks in advance for your help.
I would use the split function.
You can give it a regular expression as the argument
i.e.
line.split(" |\t");
will return array of the words ( {list[0] = Hristo, list[1] = 3} in your example)
Hope it helps.
Use split("\\s+"), this regex ignore any space, tab, etc from the String.
A more robust way might be to use regular expressions; if you received malformed input (e.g., "Ted One"), parseInt() would throw a NumberFormatException.
import java.util.regex.*;
...
Pattern p = Pattern.compile("^(.*)\\s+(\\d+)$"); // Create a regex Pattern that only matches (text - white space - integer)
Matcher m = p.matcher(line); // Create a Matcher to test the input line
if(m.find()){
// If there's a match, ..
String name = m.group(1); // Set "name" to the first parenthesized group
String value = m.group(2); // Set "value" to the second parenthesized group
}
else{
// Bad Input
}
Looks like a home work. You came really close doing it. Use StringTokenizer to tokenize the line. Then create a new member object and and call setters for both the attributes with tokens as params. If your second attribute is an int use parseInt to convert and assign it.

Categories