What is wrong with Java File read? - java

I deal with a file problem.
IBM 7918 Ayse Durlanik 7600 Computer
------------------------------------
Gama 2342 Mehmet Guzel 8300 Civil
------------------------------------
Lafarge 3242 Ahmet Bilir 4700 Chemical
------------------------------------
Intel 3255 Serhan Atmaca 9200 Electrical
------------------------------------
Bilkent 3452 Fatma Guler 2500 Computer
------------------------------------
Public 1020 Aysen Durmaz 1500 Mechanical
------------------------------------
Havelsan 2454 Sule Dilbaz 2800 Electrical
------------------------------------
Tai 3473 Fethi Oktam 3600 Computer
------------------------------------
Nurol 4973 Ayhan Ak 4100 Civil
------------------------------------
Pfizer 3000 Fusun Ot 2650 Chemical
------------------------------------
This is the text file and I don't want to read this =
"------------------------------------ "
Here is the method:
Scanner scn = null;
File fp = new File("C:/Users/Efe/Desktop/engineers.txt");
try {
scn = new Scanner(fp);
while (scn.hasNextLine()) {
{
if (!scn.next().equals("------------------------------------")) {
String comp = scn.next();
int id = Integer.parseInt(scn.next());
String name = scn.next();
String surname = scn.next();
double sal = Double.parseDouble(scn.next());
String area = scn.next();
Engineer e = new Engineer(comp, id, name, surname, sal, area);
list.add(e);
}
}
scn.close();
}
This is the code where I get an exception at run-time:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException:
For input string: "Ayse" at
java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
What is wrong with the code?

You're off by one...in the line
if (!scn.next().equals("------------------------------------")) {
if the next token is not the dashed line, then it is lost. Consider assigning it to a temporary variable.
In your case, "IBM" is lost, comp == 7918, and parseInt is called with an argument of "Ayse", leading to the runtime exception.

This is when application trying to convert string to one of the numeric types, but that string does have the appropriate format to convert.
Can you show further "IBM 7918 Ayse Durlanik 7600 Computer"

Related

reading data from a file and printing the only specific instances of the data

I am trying to manipulate this exercise but I am having a hard time executing it. Input is being scanned from a file. The information is then being formatted as its being output.
The csv file currently has the following information:
16:40,Wonders of the World,G
20:00,Wonders of the World,G
19:00,End of the Universe,NC-17
12:45,Buffalo Bill And The Indians or Sitting Bull's History Lesson,PG
15:00,Buffalo Bill And The Indians or Sitting Bull's History Lesson,PG
19:30,Buffalo Bill And The Indians or Sitting Bull's History Lesson,PG
10:00,Adventure of Lewis and Clark,PG-13
14:30,Adventure of Lewis and Clark,PG-13
19:00,Halloween,R
But my output is coming out like this:
Wonders of the World | G | 16:40
Wonders of the World | G | 20:00
End of the Universe | NC-17 | 19:00
Buffalo Bill And The Indians or Sitting Bull | PG | 12:45
Buffalo Bill And The Indians or Sitting Bull | PG | 15:00
Buffalo Bill And The Indians or Sitting Bull | PG | 19:30
Adventure of Lewis and Clark | PG-13 | 10:00
Adventure of Lewis and Clark | PG-13 | 14:30
Halloween | R | 19:00
I need to be able to only output one movie with showtimes so it looks like this.
Wonders of the World | G | 16:40 20:00
End of the Universe | NC-17 | 19:00
Buffalo Bill And The Indians or Sitting Bull | PG | 12:45 15:00 19:30
Adventure of Lewis and Clark | PG-13 | 10:00 14:30
Halloween | R | 19:00
My code so far:
public class LabProgram4 {
public static void main(String[] args) throws IOException {
String filename = "movies.csv";
int recordCount = 0;
Scanner fileScanner = new Scanner(new File(filename));
while (fileScanner.hasNextLine()) {
fileScanner.nextLine();
++recordCount;
}
String[] showtimes = new String[recordCount];
String[] title = new String[recordCount];
String[] rating = new String[recordCount];
fileScanner.close();
fileScanner = new Scanner(new File(filename));
for (int i = 0; i < recordCount; ++i) {
String[] data = fileScanner.nextLine().strip().split(",");
showtimes[i] = data[0].strip();
title[i] = data[1].strip();
rating[i] = data[2].strip();
}
fileScanner.close();
for (int i = 0; i < recordCount; ++i) {
if (title[i].length() > 44)
title[i] = title[i].substring(0, 44);
System.out.printf("%-44s | %5s | %s\n", title[i], rating[i], showtimes[i]);
}
}
}
public static final class Movie {
private String title;
private String showTime;
private String rating;
}
public static void main(String... args) throws FileNotFoundException {
List<Movie> movies = readMovies(new File("d:/movies.csv"));
Map<String, List<Movie>> map = movies.stream().collect(Collectors.groupingBy(movie -> movie.title));
print(map);
}
private static void print(Map<String, List<Movie>> map) {
int titleWidth = getTitleWidth(map);
int ratingWidth = getRatingWidth(map);
map.forEach((title, movies) -> {
String rating = movies.stream().map(movie -> movie.rating).distinct().collect(Collectors.joining(" "));
String showTime = movies.stream().map(movie -> movie.showTime).distinct().sorted().collect(Collectors.joining(" "));
System.out.format("%-" + titleWidth + "s | %-" + ratingWidth + "s | %s\n", title, rating, showTime);
});
}
private static int getTitleWidth(Map<String, List<Movie>> map) {
return map.keySet().stream()
.mapToInt(String::length)
.max().orElse(0);
}
private static int getRatingWidth(Map<String, List<Movie>> map) {
return map.values().stream()
.mapToInt(movies -> movies.stream()
.map(movie -> movie.rating)
.distinct()
.mapToInt(String::length)
.sum())
.max().orElse(0);
}
private static final int SHOW_TIME = 0;
private static final int TITLE = 1;
private static final int RATING = 2;
private static List<Movie> readMovies(File file) throws FileNotFoundException {
try (Scanner scan = new Scanner(file)) {
List<Movie> movies = new ArrayList<>();
while (scan.hasNext()) {
String[] data = scan.nextLine().split(",");
Movie movie = new Movie();
movie.title = data[TITLE].trim();
movie.showTime = data[SHOW_TIME].trim();
movie.rating = data[RATING].trim();
movies.add(movie);
}
return movies;
}
}
In my opinion, reading a file once for the sole purpose of getting the number of records (per say) is just a wrong way to go. Read the file once and carry out the task as the file is being read.
There are oodles of ways to read a file and store or display records in a unique fashion (such as no duplicate titles). Using parallel arrays to store the data is one way I suppose but these arrays need to be initialized to a specific length since they can not grow dynamically. Although not impossible, this is rather problematic in this particular situation and would require far more code to carry out the task compared to utilizing a Collection object such as a List Interface, ArrayList, (etc) which can grow dynamically.
The code below utilizes the java.util.List Interface to store and then later display Movies read in from the movies.csv file. The code looks long but it is mostly comments explaining things. I would suggest you read those comments and if you like delete them since they are excessive:
// The Movies data file name.
String filename = "movies.csv";
// Counter to keep track of the number of movies stored.
int moviesCount = 0;
// List Interface object to store movie titles in.
java.util.List<String> movies = new java.util.ArrayList<>();
// 'Try With Resources' used here to auto-close the reader
try (Scanner reader = new Scanner(new File(filename))) {
// Read the data file line by line.
String dataLine;
while (reader.hasNextLine()) {
dataLine = reader.nextLine().trim();
// Skip blank lines...
if (dataLine.isEmpty()) {
continue;
}
/* The regex ("\\s*,\\s*") passed to the String#split() method
below handles any number of whitespaces before or after the
comma delimiter on any read in data file line. */
String[] data = dataLine.split("\\s*,\\s*");
/* Do we already have title in the 'movies' List?
If so just add the show-time to the title and
continue on to the next file data line. */
boolean alreadyHave = false; // Flag that we don't already have this title
for (int i = 0; i < movies.size(); i++) {
// Do we already have the movie title in the list?
if (movies.get(i).contains(data[1])) {
// Yes we do so flag it that we already do have this title.
alreadyHave = true;
// Add the additional show-time to that title's stored information
movies.set(i, movies.get(i) + " " + data[0]);
/* Break out of this 'for' loop since there is no
more need to check other titles in the List. */
break;
}
}
/* If however we don't already have this movie title
in the List then add it in the desired display
format using the Pipe (|) character as a delimiter. */
if (!alreadyHave) {
moviesCount++; // Increment the number of movies
movies.add(String.format("%s | %s | %s", data[1], data[2], data[0]));
}
}
}
// DISPLAY THE MOVIES LIST IN TABLE STYLE FASHION
// Display Title in Console Window:
String msg = "There are " + moviesCount + " movies with various show-times:";
System.out.println(msg); // Print title
// Display Table Header:
String header = String.format("%-44s | %6s | %s", "Movie Title", "Rating", "Show Times");
String overUnderline = String.join("", java.util.Collections.nCopies(header.length(), "="));
// Header Overline
System.out.println(overUnderline);
System.out.println(header);
// Header Underline
System.out.println(overUnderline);
// Display the movies in console window.
for (String movie : movies) {
/* Split the current List element into its respective parts
using the String#split() method so that the List contents
can be displayed in a table format. The regex passed t0
the 'split()' method ("\\s*\\|\\s*") will take care of any
whitespaces before or after any Pipe (|) delimiter so that
String#trim() or String#strip() is not required. Note that
the Pipe (|) delimiter needs to be escaped (\\|) within the
expression so as to acquire is literal meaning since it is
a regex meta character. */
String[] movieParts = movie.split("\\s*\\|\\s*");
/* 'Ternary Operators' are used in the String#format() data
section components so to truncate movie Title Names to the
desire table cell width of 44 and to convert Rating and
Show-Times to "N/A" should they EVER be empty (contain no
data). */
System.out.println(String.format("%-44s | %6s | %s",
(movieParts[0].length() > 44 ? movieParts[0].substring(0, 44) : movieParts[0]),
(movieParts[1].isEmpty() ? "N/A" : movieParts[1]),
(movieParts[2].isEmpty() ? "N/A" : movieParts[2])));
}
System.out.println(overUnderline);
If the data file actually contains what you've indicated in your post then the code above will display the following into the Console Window:
There are 5 movies with various show-times:
==================================================================
Movie Title | Rating | Show Times
==================================================================
Wonders of the World | G | 16:40 20:00
End of the Universe | NC-17 | 19:00
Buffalo Bill And The Indians or Sitting Bull | PG | 12:45 15:00 19:30
Adventure of Lewis and Clark | PG-13 | 10:00 14:30
Halloween | R | 19:00
==================================================================

libphonenumber library does not extract phone numbers with prefix +34 (0)

I am using libphonenumber to extract phone number from a given String but it has failed to extract numbers with "+34 (0)" prefix (+34 prefix works fine). It works fine with other extensions (ie :- +38 (0) ). It looks like it is linked to +34 combined with (0) pattern. Following is the code sample. Anyone experienced this before?
String content = someString + "+34 (0)xxx - xxxxxx" + someString;
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
Iterable<PhoneNumberMatch> intlNumbers = phoneNumberUtil.findNumbers(content, null);
You can use parse method then get nationalNumber and countryCode
public static void main(String[] args) throws NumberParseException {
String content = "+34 (0)123 - 456789";
PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();
PhoneNumber phoneNumber =phoneNumberUtil.parse(content, null);
System.out.println("Phone Number = "+phoneNumber.getNationalNumber());
System.out.println("Country Code = "+phoneNumber.getCountryCode());
}
Result
Phone Number = 123456789
Country Code = 34
Telephone numbers in Spain shows that 0 should have been 6 or 7. I think as not living in Spain.

How to access each element after a split

I am trying to read from a text file and split it into three separate categories. ID, address, and weight. However, whenever I try to access the address and weight I have an error. Does anyone see the problem?
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;
class Project1
{
public static void main(String[] args)throws Exception
{
List<String> list = new ArrayList<String>();
List<String> packages = new ArrayList<String>();
List<String> addresses = new ArrayList<String>();
List<String> weights = new ArrayList<String>();
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while((str = br.readLine()) != null)
{
if(str.trim().length() > 0)
{
//System.out.println(str);
//Splits the string by commas and trims whitespace
String[] result = str.trim().split("\\s*,\\s*", 3);
packages.add(result[0]);
//ERROR: Doesn't know what result[1] or result[2] is.
//addresses.add(result[1]);
//weights.add(result[2]);
System.out.println(result[0]);
//System.out.println(result[1]);
//System.out.println(result[2]);
}
}
for(int i = 0; i < packages.size(); i++)
{
System.out.println(packages.get(i));
}
}
}
Here is the text file (The format is intentional):
,123-ABC-4567, 15 W. 15th St., 50.1
456-BgT-79876, 22 Broadway, 24
QAZ-456-QWER, 100 East 20th Street, 50
Q2Z-457-QWER, 200 East 20th Street, 49
678-FGH-9845 ,, 45 5th Ave,, 12.2,
678-FGH-9846,45 5th Ave,12.2
123-A BC-9999, 46 Foo Bar, 220.0
347-poy-3465, 101 B'way,24
,123-FBC-4567, 15 West 15th St., 50.1
678-FGH-8465 45 5th Ave 12.2
Seeing the pattern in your data, where some lines start with an unneeded comma, and some lines having multiple commas as delimiter and one line not even having any comma delimiter and instead space as delimiter, you will have to use a regex that handles all these behaviors. You can use this regex which does it all for your data and captures appropriately.
([\w- ]+?)[ ,]+([\w .']+)[ ,]+([\d.]+)
Here is the explanation for above regex,
([\w- ]+?) - Captures ID data which consists of word characters hyphen and space and places it in group1
[ ,]+ - This acts as a delimiter where it can be one or more space or comma
([\w .']+) - This captures address data which consists of word characters, space and . and places it in group2
[ ,]+ - Again the delimiter as described above
([\d.]+) - This captures the weight data which consists of numbers and . and places it in group3
Demo
Here is the modified Java code you can use. I've removed some of your variable declarations which you can have them back as needed. This code prints all the information after capturing the way you wanted using Matcher object.
Pattern p = Pattern.compile("([\\w- ]+?)[ ,]+([\\w .']+)[ ,]+([\\d.]+)");
// Reads the file
try (BufferedReader br = new BufferedReader(new FileReader("data1.txt"))) {
String str;
while ((str = br.readLine()) != null) {
Matcher m = p.matcher(str);
if (m.matches()) {
System.out.println(String.format("Id: %s, Address: %s, Weight: %s",
new Object[] { m.group(1), m.group(2), m.group(3) }));
}
}
}
Prints,
Id: 456-BgT-79876, Address: 22 Broadway, Weight: 24
Id: QAZ-456-QWER, Address: 100 East 20th Street, Weight: 50
Id: Q2Z-457-QWER, Address: 200 East 20th Street, Weight: 49
Id: 678-FGH-9845, Address: 45 5th Ave, Weight: 12.2
Id: 678-FGH-9846, Address: 45 5th Ave, Weight: 12.2
Id: 123-A BC-9999, Address: 46 Foo Bar, Weight: 220.0
Id: 347-poy-3465, Address: 101 B'way, Weight: 24
Id: 678-FGH-8465, Address: 45 5th Ave, Weight: 12.2
Let me know if this works for you and if you have any query further.
The last line only contains one token. So split will only return an array with one element.
A minimal reproducing example:
import java.io.*;
class Project1 {
public static void main(String[] args) throws Exception {
//Provide the file path
File file = new File(args[0]);
//Reads the file
BufferedReader br = new BufferedReader(new FileReader(file));
String str;
while ((str = br.readLine()) != null) {
if (str.trim().length() > 0) {
String[] result = str.trim().split("\\s*,\\s*", 3);
System.out.println(result[1]);
}
}
}
}
With this input file:
678-FGH-8465 45 5th Ave 12.2
The output looks like this:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at Project1.main(a.java:22)
Process finished with exit code 1
So you will have to decide, what your program should do in such cases. You might ignore those lines, print an error, or only add the first token in one of your lists.
you can add following code in your code
if (result.length > 0) {
packages.add(result[0]);
}
if (result.length > 1) {
addresses.add(result[1]);
}
if (result.length > 2) {
weights.add(result[2]);
}

Reading from the File

This program has 2 classes with a main method and is supposed to read from a file. My problem is that the line double listPrice = fileScan.nextDouble(); gives an error exception like this Exception in thread "main" java.util.InputMismatchException. The error is in this class:
Here is contents of the file:
Honda Accord
2004 16780.00 10.0
Chrysler SUV
2002 8600.00 0.0
Toyota Camry
2007 21799.99 3.0
Ford Escort
2006 12345.78 5.5
//note there is no space between each line
class Proj1P2CarAryListService
{
private ArrayList<Proj1CarData> carList = new ArrayList<Proj1CarData>();
public Proj1P2CarAryListService()
{
carList = new ArrayList<Proj1CarData>();
}
public void readStoreCarsData()
{
Scanner scan = new Scanner(System.in);
Scanner fileScan;
boolean validName = false;
double discountAmount;
double netPrice;
do
{
System.out.print("Enter file name: ");
String str1 = scan.nextLine();
try
{
fileScan = new Scanner(new File(str1));
validName = true;
while (fileScan.hasNext())
{
String name = fileScan.nextLine();
String modelYear = fileScan.next();
double listPrice = fileScan.nextDouble();
double percentDiscount = fileScan.nextDouble();
discountAmount = listPrice * percentDiscount/100.0;
netPrice = listPrice - discountAmount;
Proj1CarData proj1 = new Proj1CarData(name, modelYear, listPrice, percentDiscount, discountAmount, netPrice);
carList.add(proj1);
System.out.println(proj1.toString());
}// end while
}// end try
catch (FileNotFoundException fnfe)
{
System.out.println("Invalid File name; enter again");
}
} while (!validName);
}//readStoreCarsData
This exception is thrown by a Scanner to indicate that the token retrieved does not match the pattern for the expected type(Double must be separated by . or , like said jlordo), or that the token is out of range for the expected type. Perhaps it is a file content problem.
The nextDouble() method of Scanner is locale-aware (see Documentation).
This means, if your locale is set to a country where '.' seperates a floating point number following would be a parsable double value: 123.456 while following number will give you a InputMismatchException 123,456. In Europe 123,456 would work, and 123.456 would throw an Exception. Hope it helps...
You might want to consider printing out each line. You might be getting more than you expect.

InputMismatchException Error in Java

public static void readStaffsFromFile() {
String inFileName = "startup.txt";
int numStaff, staffID;
String name, address;
Staff newStaff;
boolean fileExists;
Scanner inFile = null;
File databaseFile = new File(inFileName);
fileExists = databaseFile.exists();
if (fileExists) {
try {
inFile = new Scanner(databaseFile);
} catch (FileNotFoundException fnfe) {
JOptionPane.showMessageDialog(null, "The file startup.txt has just now been deleted.");
return; // cannot do anything more.
}
numStaff = inFile.nextInt();
inFile.nextLine();
for (int i = 0; i < numStaff; i++) {
staffID = inFile.nextInt();
name = inFile.nextLine();
address = inFile.nextLine();
// try{
newStaff = new Staff(staffID, name, address);
addStaff(newStaff);
// } catch (StaffException se)
// {
// System.out.println("Unable to add staff: " + name +
// " to the system.");
// }
}
}
JOptionPane.showMessageDialog(null, "System has been set up with default data from startup.txt.");
}
I have this method and when I try to call this method from main, it gives me this error.
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:909)
at java.util.Scanner.next(Scanner.java:1530)
at java.util.Scanner.nextInt(Scanner.java:2160)
at java.util.Scanner.nextInt(Scanner.java:2119)
at SystemStartUp.readStaffsFromFile(SystemStartUp.java:195)
at SystemStartUp.loadFromFile(SystemStartUp.java:160)
at StartUp.main(StartUp.java:9)
The error line of error states that my error starts from the line of "staffID = inFile.nextInt();"
The input file looks like this.
13
11111111
Chris Ling
999 Dandenong Road
22222222
Des Casey
100 Silly Drive
33333333
Maria Indrawan
90 Programming Road
44444444
Campbell Wilson
2/5 Database Street
55555555
Janet Fraser
21 Web Drive
66666666
Judy Sheard
34 Hos Road
77777777
Ngoc Minh
24 Message Street
88888888
Martin Atchinson
45 Martine Street
99999999
Aleisha Matthews
1/6 Admin Road
10101010
Denyse Cove
100 Reception Street
12121212
Cornelia Liou
232 Reception Road
23232323
Trudi Robinson
111 Manager Street
34343434
Henry Linger
2/4 HDR Street
Probably the staffID doesn't always contains numbers. Please check the input file.
After staffID, you have to add inFile.nextLine(); to consume the new line character after of the line with number. Otherwise, you will get the error on the second loop.

Categories

Resources