I've to read data from a file and I've just entered some sample data as a String in StringTokenizer. I can't understand what is wrong with my code here. Can someone please advise?
import java.util.StringTokenizer;
public class rough {
public static void main(String[] args) throws Exception {
StringTokenizer itr = new StringTokenizer("PKE2324 02-12-2020 200"
+ "\nMJD432 19-05-2019 150");
while (itr.hasMoreTokens()){
String line = itr.nextToken().toString();
String[] tokens = line.split(" ");
String[] date = tokens[1].split("-");
String yr = date[2];
String reg = tokens[0];
String regy = new String(reg + " " + yr);
System.out.println(regy);
}
}
}
I want to get the registration number and year as a String. When I run this, I keep getting ArrayIndexOutofBounds
This is the type of runtime error which has been caused due to logical error and inappropriate delimeter.
Assuming you want to tokenise the big string using newline character, use, \n as delimeter to StringTokenizer.
Have a look at the corrected code below which satisfies your use case:
import java.util.StringTokenizer;
public class rough {
public static void main(String[] args) throws Exception {
StringTokenizer itr = new StringTokenizer("PKE2324 02-12-2020 200"
+ "\nMJD432 19-05-2019 150", "\n");
while (itr.hasMoreTokens()){
String line = itr.nextToken().toString();
String[] tokens = line.split(" ");
String[] date = tokens[1].split("-");
String yr = date[2];
String reg = tokens[0];
String regy = new String(reg + " " + yr);
System.out.println(regy);
}
}
}
Output:
PKE2324 2020
MJD432 2019
Exception caused by this line
String[] tokens = line.split(" ");
String[] date = tokens[1].split("-");
line = PKE2324, so tokens[] = { "PKE2324" } --> length = 1
tokens[1] --> ArrayIndexOutOfBoundException
To fix this:
StringTokenizer itr = new StringTokenizer("PKE2324 02-12-2020 200"
+ "\nMJD432 19-05-2019 150");
Default delimeter is whitespace.
You should pass delimeter in constructor if you want different delimeter.
Related
I have a problem with my code.
I'm trying to extract the name of the channels from a .txt file.
I can't understand why the method line.split() give me back an array with 0 length:
Someone can help me?
This is the file .txt:
------------[channels.txt]---------------------
...
#CH id="" tvg-name="Example1" tvg-logo="http...
#CH id="" tvg-name="Example2" tvg-logo="http...
#CH id="" tvg-name="Example3" tvg-logo="http...
#CH id="" tvg-name="Example4" tvg-logo="http...
...
This is my code:
try {
FileInputStream VOD = new FileInputStream("channels.txt");
BufferedReader buffer_r = new BufferedReader(new InputStreamReader(VOD));
String line;
ArrayList<String> name_channels = new ArrayList<String>();
while ((line = buffer_r.readLine()) != null ) {
if (line.startsWith("#")) {
String[] first_scan = line.split(" tvg-name=\" ", 2);
String first = first_scan[1]; // <--- out of bounds
String[] second_scan = first.split(" \"tvg-logo= ", 2);
String second = second_scan[0];
name_channels.add(second);
} else {
//...
}
}
for (int i = 0; i < name_channels.size(); i++) {
System.out.println("Channel: " + name_channels.get(i));
}
} catch(Exception e) {
System.out.println(e);
}
So you have examples like this
#CH id="" tvg-name="Example1" tvg-logo="http...
And are trying to split on these strings
" tvg-name=\" "
" \"tvg-logo= "
Neither of those strings are in the example. There's a spurious space appended, and the space at the start of the second is in the wrong place.
Fix the strings and here's a concise but complete program to demonstrate
interface Split {
static void main(String[] args) {
String line = "#CH id=\"\" tvg-name=\"Example1\" tvg-logo=\"http...";
String[] first_scan = line.split(" tvg-name=\"", 2);
String first = first_scan[1]; // <--- out of bounds
String[] second_scan = first.split("\" tvg-logo=", 2);
String second = second_scan[0];
System.err.println(second);
}
}
Of course, if you have any lines that start with '#' but don't match, you'll have a similar problem.
This sort of thing is probably done better with regexs and capturing groups.
There is a whitespace after the last double quote in tvg-name=\" which does not match the data in your example.
When you use split with line.split(" tvg-name=\"", 2) then the first item in the returned array will be #CH id="" and the second part will be Example1" tvg-logo="http..."
If you want to get the value of tvg-name= you might use a regex with a capturing group where you would capture not a double quote using a negated character class [^"]+
tvg-name="([^"]+)"
try {
FileInputStream VOD = new FileInputStream("channels.txt");
BufferedReader buffer_r = new BufferedReader(new InputStreamReader(VOD));
String line;
ArrayList<String> name_channels = new ArrayList<String>();
while((line = buffer_r.readLine()) != null ){
if(line.startsWith("#")){
String regex = "tvg-name=\"([^\"]+)\"";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {
name_channels.add(matcher.group(1));
}
} else {
// ...
}
}
for(int i = 0; i < name_channels.size(); i++){
System.out.println("Channel: " + name_channels.get(i));
}
}catch(Exception e){
System.out.println(e);
}
I have got a text like this in my String s (which I have already read from txt.file)
trump;Donald Trump;trump#yahoo.eu
obama;Barack Obama;obama#google.com
bush;George Bush;bush#inbox.com
clinton,Bill Clinton;clinton#mail.com
Then I'm trying to cut off everything besides an e-mail address and print out on console
String f1[] = null;
f1=s.split("(.*?);");
for (int i=0;i<f1.length;i++) {
System.out.print(f1[i]);
}
and I have output like this:
trump#yahoo.eu
obama#google.com
bush#inbox.com
clinton#mail.com
How can I avoid such output, I mean how can I get output text without line breakers?
Try using below approach. I have read your file with Scanner as well as BufferedReader and in both cases, I don't get any line break. file.txt is the file that contains text and the logic of splitting remains the same as you did
public class CC {
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner(new File("file.txt"));
while (scan.hasNext()) {
String f1[] = null;
f1 = scan.nextLine().split("(.*?);");
for (int i = 0; i < f1.length; i++) {
System.out.print(f1[i]);
}
}
scan.close();
BufferedReader br = new BufferedReader(new FileReader(new File("file.txt")));
String str = null;
while ((str = br.readLine()) != null) {
String f1[] = null;
f1 = str.split("(.*?);");
for (int i = 0; i < f1.length; i++) {
System.out.print(f1[i]);
}
}
br.close();
}
}
You may just replace all line breakers as shown in the below code:
String f1[] = null;
f1=s.split("(.*?);");
for (int i=0;i<f1.length;i++) {
System.out.print(f1[i].replaceAll("\r", "").replaceAll("\n", ""));
}
This will replace all of them with no space.
Instead of split, you might match an email like format by matching not a semicolon or a whitespace character one or more times using a negated character class [^\\s;]+ followed by an # and again matching not a semicolon or a whitespace character.
final String regex = "[^\\s;]+#[^\\s;]+";
final String string = "trump;Donald Trump;trump#yahoo.eu \n"
+ " obama;Barack Obama;obama#google.com \n"
+ " bush;George Bush;bush#inbox.com \n"
+ " clinton,Bill Clinton;clinton#mail.com";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
final List<String> matches = new ArrayList<String>();
while (matcher.find()) {
matches.add(matcher.group());
}
System.out.println(String.join("", matches));
[^\\s;]+#[^\\s;]+
Regex demo
Java demo
package com.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String s = "trump;Donald Trump;trump#yahoo.eu "
+ "obama;Barack Obama;obama#google.com "
+ "bush;George Bush;bush#inbox.com "
+ "clinton;Bill Clinton;clinton#mail.com";
String spaceStrings[] = s.split("[\\s,;]+");
String output="";
for(String word:spaceStrings){
if(validate(word)){
output+=word;
}
}
System.out.println(output);
}
public static final Pattern VALID_EMAIL_ADDRESS_REGEX = Pattern.compile(
"^[A-Z0-9._%+-]+#[A-Z0-9.-]+\\.[A-Z]{2,6}$",
Pattern.CASE_INSENSITIVE);
public static boolean validate(String emailStr) {
Matcher matcher = VALID_EMAIL_ADDRESS_REGEX.matcher(emailStr);
return matcher.find();
}
}
Just replace '\n' that may arrive at start and end.
write this way.
String f1[] = null;
f1=s.split("(.*?);");
for (int i=0;i<f1.length;i++) {
f1[i] = f1[i].replace("\n");
System.out.print(f1[i]);
}
I develop using Java to make a little project.
I want String reverse.
If I entered "I am a girl", Printed reversing...
Already I tried to use StringBuilder.
Also I write it using StringBuffer grammar...
But I failed...
It is not printed my wish...
WISH
My with Print -> "I ma a lrig"
"I am a girl" -> "I ma a lrig" REVERSE!!
How can I do?..
Please help me thank you~!!!
public String reverse() {
String[] words = str.split("\\s");
StringTokenizer stringTokenizer = new StringTokenizer(str, " ");
for (String string : words) {
System.out.print(string);
}
String a = Arrays.toString(words);
StringBuilder builder = new StringBuilder(a);
System.out.println(words[0]);
for (String st : words){
System.out.print(st);
}
return "";
}
Java 8 code to do this :
public static void main(String[] args) {
String str = "I am a girl";
StringBuilder sb = new StringBuilder();
// split() returns an array of Strings, for each string, append it to a StringBuilder by adding a space.
Arrays.asList(str.split("\\s+")).stream().forEach(s -> {
sb.append(new StringBuilder(s).reverse() + " ");
});
String reversed = sb.toString().trim(); // remove trailing space
System.out.println(reversed);
}
O/P :
I ma a lrig
if you do not want to go with lambda then you can try this solution too
String str = "I am a girl";
String finalString = "";
String s[] = str.split(" ");
for (String st : s) {
finalString += new StringBuilder(st).reverse().append(" ").toString();
}
System.out.println(finalString.trim());
}
I'm reading from the file:
name1 wordx wordy passw1
name2 wordx wordy passw2
name3 wordx wordy passw3
name (i) wordx wordy PASSW (i)
x
x word
x words
words
x
words
At the moment I can print line by line:
Line 1: name1 wordx wordy passw1
Line 2: name2 wordx wordy passw2
I plan to have access to:
users [0] = name1
users [1] = name2
users [2] = name3
..
passws [0] = passw1
passws [1] = passw2
passws [2] = passw3
..
My code is:
public static void main(String args[]) throws FileNotFoundException, IOException {
ArrayList<String> list = new ArrayList<String>();
Scanner inFile = null;
try {
inFile = new Scanner(new File("C:\\file.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (inFile.hasNextLine()) {
list.add(inFile.nextLine()+",");
}
String listString = "";
for (String s : list) {
listString += s + "\t";
}
String[] parts = listString.split(",");
System.out.println("Line1: "+ parts[0]);
}
How do I get the following output:
User is name1 and password is passw1
User is name32 and password is passw32
Thanks in advance.
Something like this will do:
public static void main(String args[]) throws FileNotFoundException, IOException {
ArrayList<String> list = new ArrayList<String>();
Scanner inFile = null;
try {
inFile = new Scanner(new File("C:\\file.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (inFile.hasNextLine()) {
list.add(inFile.nextLine());
}
int line = 0;
String[] parts = list.get(line).split(" ");
String username = parts[0];
String pass = parts[3];
System.out.println("Line" + (line + 1) + ": " + "User is " + username +" and password is " + pass);
}
EDIT: if you want to iterate through all lines just put last lines in a loop:
for (int line = 0; line < list.size(); line++) {
String[] parts = list.get(line).split(" ");
String username = parts[0];
String pass = parts[3];
System.out.println("Line" + (line + 1) + ": " + "User is " + username +" and password is " + pass);
}
First thing to do is, to add this loop to the end of your code :
for(int i = 0; i <= parts.length(); i++){
System.out.println("parts["+i+"] :" + parts[i] );
}
that will simply show the result of the split using ,.
Then adapt your code, you may want to use another regex to split() your lines, for instance a space.
String[] parts = listString.split(" ");
for documentation about split() method check this.
If you want to get that output then this should do the trick:
public static void main(String args[]) throws FileNotFoundException, IOException {
Scanner inFile = null;
try {
inFile = new Scanner(new File("F:\\file.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Map<String, String> userAndPassMap = new LinkedHashMap<>();
while (inFile.hasNextLine()) {
String nextLine = inFile.nextLine();
String[] userAndPass = nextLine.split(" ");
userAndPassMap.put(userAndPass[0], userAndPass[1]);
}
for (Map.Entry<String, String> entry : userAndPassMap.entrySet()) {
System.out.println("User is:" + entry.getKey() + " and password is:" + entry.getValue());
}
}
By storing in a map you are linking directly each username with its password. If you need to save them into separate arrays then you can do this in the while loop instead:
List<String> users = new LinkedList<>(),passwords = new LinkedList<>();
while (inFile.hasNextLine()) {
String nextLine = inFile.nextLine();
String[] userAndPass = nextLine.split(" ");
users.add(userAndPass[0]);
passwords.add(userAndPass[1]);
}
and later transform them to arrays
users.toArray()
I recommend you use a java.util.Map, a standard API which allows you to store objects and read each one of them by a key. (In your case, string objects indexed by string keys). Example:
Let's assume this empty map:
Map<String, String> map=new HashMap<String,String>();
If you store this:
map.put("month", "january");
map.put("day", "sunday");
You can expect that map.get("month") will return "january", map.get("day") will return "sunday", and map.get(any-other-string) will return null.
Back to your case: First, you must create and populate the map:
private Map<String, String> toMap(Scanner scanner)
{
Map<String, String> map=new HashMap<String, String>();
while (scanner.hasNextLine())
{
String line=scanner.nextLine();
String[] parts=line.split(" ");
// Validation: Process only lines with 4 tokens or more:
if (parts.length>=4)
{
map.put(parts[0], parts[parts.length-1]);
}
}
return map;
}
And then, to read the map:
private void listMap(Map<String,String> map)
{
for (String name : map.keySet())
{
String pass=map.get(name);
System.out.println(...);
}
}
You must include both in your class and call them from the main method.
If you need arbitraray indexing of the read lines, use ArrayList:
First, define a javabean User:
public class User
{
private String name;
private String password;
// ... add full constructor, getters and setters.
}
And then, you must create and populate the list:
private ArrayList<User> toList(Scanner scanner)
{
List<User> list=new ArrayList<User>();
while (scanner.hasNextLine())
{
String line=scanner.nextLine();
String[] parts=line.split(" ");
// Validation: Process only lines with 4 tokens or more:
if (parts.length>=4)
{
list.add(new User(parts[0], parts[parts.length-1]));
}
}
return list;
}
I have a text file:
John Smith 2009-11-04
Jenny Doe 2009-12-29
Alice Jones 2009-01-03
Bob Candice 2009-01-04
Carol Heart 2009-01-07
Carlos Diaz 2009-01-10
Charlie Brown 2009-01-14
I'm trying to remove the dashes and store them as separate types: first, last, year,month,day and then add it to a sortedset/hashmap. But for some reason. It's not working right.
Here is my code:
public class Test {
File file;
private Scanner sc;
//HashMap<Name, Date> hashmap = new HashMap<>();
/**
* #param filename
*/
public Test(String filename) {
file = new File(filename);
}
public void openFile(String filename) {
// open the file for scanning
System.out.println("Test file " + filename + "\n");
try {
sc = new Scanner(new File("birthdays.dat"));
}
catch(Exception e) {
System.out.println("Birthdays: Unable to open data file");
}
}
public void readFile() {
System.out.println("Name Birthday");
System.out.println("---- --------");
System.out.println("---- --------");
while (sc.hasNext()) {
String line = sc.nextLine();
String[] split = line.split("[ ]?-[ ]?");
String first = split[0];
String last = split[1];
//int year = Integer.parseInt(split[2]);
//int month = Integer.parseInt(split[3]);
//int day = Integer.parseInt(split[4]);
Resource name = new Name(first, last);
System.out.println(first + " " + last + " " + split[2] );
//hashmap.add(name);
}
}
public void closeFile() {
sc.close();
}
public static void main(String[] args) throws FileNotFoundException,
ArrayIndexOutOfBoundsException {
try {
Scanner sc = new Scanner( new File(args[0]) );
for( int i = 0; i < args.length; i++ ) {
//System.out.println( args[i] );
if( args.length == 0 ) {
}
else if( args.length >= 1 ) {
}
// System.out.printf( "Name %-20s Birthday", name.toString(), date.toString() );
}
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println("Usage: Birthdays dataFile");
// Terminate the program here somehow, or see below.
System.exit(-1);
} catch (FileNotFoundException e) {
System.err.println("Birthdays: Unable to open data file");
// Terminate the program here somehow, or see below.
System.exit(-1);
}
Test r = new Test(args[0]);
r.openFile(args[0]);
r.readFile();
r.closeFile();
}
}
Your splitting on dashes but your is program is build around a split using spaces.
Try just splitting on spaces
String[] split = line.split("\\s");
So "John Smith 2009-11-04".split("[ ]?-[ ]?"); results in ["John Smith 2009", "11", "04"] When what you want is for it to split on spaces ["John", "Smith", "2009-11-04"]
I would do this differently, first create a domain object:
public class Person {
private String firstName;
private String lastName;
private LocalDate date;
//getters & setters
//equals & hashCode
//toString
}
Now create a method that parses a single String of the format you have to a Person:
//instance variable
private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public Person parsePerson(final String input) {
final String[] data = input.split("\\s+");
final Person person = new Person();
person.setFirstName(data[0]);
person.setLastName(data[1]);
person.setDate(LocalDate.parse(data[2], dateTimeFormatter));
return person;
}
Note that the DateTimeFormatter is an instance variable, this is for speed. You should also set the ZoneInfo on the formatter if you need to parse dates not in your current locale.
Now, you can read your file into a List<Person> very easily:
public List<Person> readFromFile(final Path path) throws IOException {
try (final Stream<String> lines = Files.lines(path)) {
return lines
.map(this::parsePerson)
.collect(toList());
}
}
And now that you have a List<Person>, you can sort or process them however you want.
You can even do this while creating the List:
public List<Person> readFromFile(final Path path) throws IOException {
try (final Stream<String> lines = Files.lines(path)) {
return lines
.map(this::parsePerson)
.sorted(comparing(Person::getLastName).thenComparing(Person::getFirstName))
.collect(toList());
}
}
Or have your Person implements Comparable<Person> and simply use natural order.
TL;DR: Use Objects for your objects and life becomes much simpler.
I would use a regex:
private static Pattern LINE_PATTERN
= Pattern.compile("(.+) (.+) ([0-9]{4})-([0-9]{2})-([0-9]{2})");
...
while (sc.hasNext()) {
String line = sc.nextLine();
Matcher matcher = LINE_PATTERN.matcher(line);
if (!matcher.matches()) {
// malformed line
} else {
String first = matcher.group(1);
String last = matcher.group(2);
int year = Integer.parseInt(matcher.group(3));
int month = Integer.parseInt(matcher.group(4));
int day = Integer.parseInt(matcher.group(5));
// do something with it
}
}
You are splitting on spaces and a hyphen. This pattern does not exist.
String[] split = line.split("[ ]?");
String first = split[0];
String last = split[1];
line = split[2];
//now split the date
String[] splitz = line.split("-");
or something like this might work:
String delims = "[ -]+";
String[] tokens = line.split(delims);
If i understood your question right then Here is answer. Check it out.
List<String> listGet = new ArrayList<String>();
String getVal = "John Smith 2009-11-04";
String[] splited = getVal.split("[\\-:\\s]");
for(int j=0;j<splited.length;j++)
{
listGet.add(splited[j]);
}
System.out.println("first name :"+listGet.get(0));
System.out.println("Last name :"+listGet.get(1));
System.out.println("year is :"+listGet.get(2));
System.out.println("month is :"+listGet.get(3));
System.out.println("day is :"+listGet.get(4));
OP :
first name :John
Last name :Smith
year is :2009
month is :11
day is :04