my program is meant to read from a txt and print certain parts of it. when i try to set Double d4 it gives me an error saying that string is
empty although it's not. and it's also not an issue of formatting since d1-5 worked fine when i removed the line. i also printed data[5] and that showed the proper line from the txt.
import java.util.Scanner;
import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class AAAAAA {
public static void main (String[] args)throws IOException {
final String fileName = "classQuizzes.txt";
//1)
Scanner sc = new Scanner(new File(fileName));
//declarations
String input;
double total = 0.0;
double num = 0;
double count = 0;
double average = 0;
String lastName;
String firstName;
double minimum;
double max;
//2) process rows
input = sc.nextLine();
System.out.println(input);
while (sc.hasNextLine()) {
String line = sc.nextLine();
System.out.println(line);
// split the line into pieces of data separated by the spaces
String[] data = line.split(" ");
// get the name from data[]
System.out.println("d5 " +data[4]);
firstName = data[0];
lastName = data[1];
Double d1 = Double.valueOf(data[2]);
Double d2 = Double.valueOf(data[3]);
Double d3 = Double.valueOf(data[4]);
Double d4 = Double.valueOf(data[5]);
Double d5 = Double.valueOf(data[6]);
// do the same...
System.out.println("data " + d3);
total += d1 + d2 + d3 + d5;
count++;
//find average (decimal 2 points)
System.out.println(count);
average = total / count;
System.out.println("Total = " + total);
System.out.println("Average = " + average);
//3) class statistics
//while
}
System.out.println("Program created by");
}
}
The line might not be empty, but when you split it at spaces, if there are two spaces in a row, you will get empty strings in the split. To prevent this, change
String[] data = line.split(" ");
to
String[] data = line.split(" *");
or, perhaps better, since it will deal with tabs and other white space:
String[] data = line.split("\\s*");
To track down these kinds of problems yourself (and to verify that I've diagnosed the problem correctly), you should print out each element of the split array, as well as verify the array length is what you expect.
Related
I am given a messy set of data and have to split the data into categories. The first line is tax rate, The following line is supposed to be "items," "number of items," and price (columns). I just need help splitting the data accordingly. Any help would be appreciated.
0.05 5
Colored Pencils 3 0.59
Notebook 5 0.99
AAA Battery 5 0.99
Java Book 5 59.95
iPhone X 2 999.99
iPhone 8 3 899.99.
import java.io.*;
import java.util.Scanner;
public class ShoppingBagClient {
public static void main(String[] args) {
File file = new File("data.txt");
shoppingBag(file);
}
public static void shoppingBag (File file) {
Scanner scan;
String itemName=" ";
int quantity = 0;
float price = 0;
int count = 0;
float taxRate;
ShoppingBag shoppingBag = new ShoppingBag(6, .5f);
try {
scan = new Scanner(new BufferedReader(new FileReader(file)));
String dilimeter;
while(count < 1) {
String line = scan.nextLine();
String[] arr = line.split(" ");
taxRate = Float.parseFloat(arr[0]);
}
while(scan.hasNextLine() && count > 0){
String line = scan.nextLine();
String delimeter;
String arr[] = line.split();
itemName = arr[0];
quantity = Integer.parseInt(arr[1]);
price = Float.parseFloat(arr[2]);
Item item =``` new Item(itemName, quantity, price);
shoppingBag.push(item);
System.out.println(itemName);
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
#Henry's comment gives a good approach. If you know the structure of each line and that it is delimited in a consistent manner (e.g. single space-separated) then you can combine lastIndexOf and substring to do the job.
String delimiter = " ";
String line = scan.nextLine(); // "Colored pencils 3 0.59"
int last = line.lastIndexOf(delimiter); // "Colored pencils 3_0.59"
String price = line.substring(last + 1); // "0.59"
line = line.substring(0, last); // "Colored pencils 3"
last = line.lastIndexOf(delimiter); // "Colored pencils_3"
String quantity = line.substring(last + 1); // "3"
line = line.substring(0, last); // "Colored pencils"
String product = line;
This can be refactored to be tidier but illustrates the point. Be mindful that if lastIndexOf returns the final character in the line then substring(last + 1) will throw a StringIndexOutOfBoundsException. A check should also be taken for if lastIndexOf does not find a match in which case it will return -1.
Edit: The price and quantity can then be converted to an int or float as necessary.
Because the item name doesn't have any restrictions, and as shown can include both spaces and numbers, it would be difficult to start processing the line from the beginning. On the other hand processing from the end is easier.
Consider this change to your code:
String arr[] = line.split();
int len = arr.length;
double price = Float.parseFloat(arr[len - 1]);
double quantity = Integer.parseInt(arr[len - 2]);
String itemName = "";
for(int i = 0; i < len - 2; i++)
itemName += arr[i] + " ";
This works because you know the last element will always be the price, and the pre last will always be the quantity. Therefore the rest of the array contains the name.
alternatively you could use a java 8 implementation for acquiring the name:
itemName = Stream.of(values).limit(values.length -2).collect(Collectors.joining(" "));
Have to add extra line "String x=in.readLine();" after reading character "sec=(char)in.read();" otherwise program is not proceeding further to take more inputs, see comment below in code. Please note I don't want to use scanner class.
import java.io.*;
class marks
{
public static void main(String args[])
{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int rl,m1,m2,m3,tot=0;
String nm,cl;
nm=cl="";
char sec='A';
double avg=0.0d;
try
{
System.out.println("Enter the information of the student");
System.out.print("roll no:");
rl=Integer.parseInt(in.readLine());
System.out.print("class:");
cl=in.readLine();
System.out.print("section:");
sec=(char)in.read();
String x=in.readLine(); /* have to add this line only then marks of 3 subject can be inputed */
System.out.println("marks of three subjects "+x);
m1=Integer.parseInt(in.readLine());
m2=Integer.parseInt(in.readLine());
m3=Integer.parseInt(in.readLine());
tot=m1+m2+m3;
avg=tot/3.0d;
System.out.println("total marks of the students = "+tot);
System.out.println("avg marks of the students = "+avg);
}
catch (Exception e)
{};
}
}
How about replacing:
sec=(char)in.read();
with:
sec = in.readLine().charAt(0);
solved
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Marks {
public static void main(String args[]) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(System.in))) {
int rl, m1, m2, m3, tot = 0;
String nm, cl;
nm = cl = "";
char sec = 'A';
double avg = 0.0d;
System.out.println("Enter the information of the student");
System.out.print("roll no:");
rl = Integer.parseInt(in.readLine());
System.out.print("class:");
cl = in.readLine();
System.out.print("section:");
sec = in.readLine().charAt(0); //changes are here, instead of
// String x = in.readLine(); /* have to add this line only then marks of 3
// subject can be inputed */
System.out.println("marks of three subjects ");
m1 = Integer.parseInt(in.readLine());
m2 = Integer.parseInt(in.readLine());
m3 = Integer.parseInt(in.readLine());
tot = m1 + m2 + m3;
avg = tot / 3.0d;
System.out.println("total marks of the students = " + tot);
System.out.println("avg marks of the students = " + avg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output
Enter the information of the student
roll no:21
class:10
section:c
marks of three subjects
56
65
56
total marks of the students = 177
avg marks of the students = 59.0
The problem is when you use in.read() according to documentation:"Reads a single character," but you are actually typing 'two' characters: one char and one '\n' which is stored in the InputStreamReader's buffer and will be read again when you use in.readLine();
I'm having an issue with this particular program. To cut a long story short, what this program is supposed to do is to get input from a text file, in this case the names and scores of bowlers, and read data off of it. The issue I'm having is trying to extract the scores from the file and storing them in separate variables.
`
import java.util.*;
import java.io.*;
public class lab5{
public static void main (String args[]) throws IOException {
String bowler;
String name;
int score1 = 0, score2 = 0, score3 = 0;
int game = 0;
int average = 0;
//Scanner scan = new Scanner (new FileReader("bowl1.txt."));
Scanner scan = new Scanner (new File ("bowl1.txt"));
while (scan.hasNext()){
bowler = scan.nextLine();
System.out.println("\n" + bowler);
String charCheck = "";
String indent = "";
int count = bowler.length() - 1;
while (count <= bowler.length()){
indent = bowler.lastIndexOf(" ");
charCheck = bowler.substring(0,indent);
System.out.println(charCheck);
count++;
score1 = Integer.parseInt(charCheck);
score2 = Integer.parseInt(charCheck);
score3 = Integer.parseInt(charCheck);
}//end while
System.out.println(score1 + score2 + score3);
}//end fileScan while
}//end main
}//end class
I apologize that my code is a bit sloppy, but I am still learning some of the basics of java. Basically, the idea here is that I need to use the Substring and lastIndexOf(" ") methods to read the scores from the file, and then using Integer.parseInt() to turn them into integers.
(The file is called "bowl1.txt", and this is the data on it)
Atkison, Darren 188 218 177
Barnes, Chris 202 194 195
Dolan, Anthony 203 193 225
Easton, Charles 255 213 190
Any help or hints on what I'm missing would be greatly appreciated.
When you call bowler.substring(0, indent) you actually substring the name of the bowler, so it doesn't contains the scores.
If you want to get only the scores part of the string, use bowler.substring(indent + 1, bowler.length). You still have to break it to 3 different strings and convert each one of them into a integer.
Anyway, a better approach will be to split each line into an array of strings using String#split print the first strings, since it is the bowler name and then convert the last 3 into integers. You can also use Scanner#nextInt() and Scanner#nextString() methods, since the structure of the file is known.
Introduced a class Bowler to store each row of data. You can now use the list of bowler objects to continue your process. String.split() gives an array of Strings tokenized based on the character specified. Space has been used here to split.
import java.util.*;
import java.io.*;
public class lab5 {
public static void main(String args[]) throws IOException {
Scanner scan = new Scanner(new File("C:\\TEMP\\bowl1.txt"));
String bowler;
List<Bowler> bowlers = new ArrayList<Bowler>();
while (scan.hasNext()) {
bowler = scan.nextLine();
if (!bowler.trim().equals("")) {
System.out.println("\n" + bowler);
String[] tokens = bowler.split(" ");
Bowler b = new Bowler(tokens[0], tokens[1], Integer.parseInt(tokens[2]), Integer.parseInt(tokens[3]),
Integer.parseInt(tokens[4]));
bowlers.add(b);
}
} // end fileScan while
for (Bowler bow : bowlers) {
System.out.println(bow.score1 + ", " + bow.score2 + ", " + bow.score3);
}
}// end main
}// end class
class Bowler {
String firstName;
String lastName;
int score1;
int score2;
int score3;
public Bowler(String firstName, String lastName, int score1, int score2, int score3) {
this.firstName = firstName;
this.lastName = lastName;
this.score1 = score1;
this.score2 = score2;
this.score3 = score3;
}
}
Okay this is a straight forward method....it is done only using lastIndexOf(" ") and substring("") method as you said. but there are lot efficient and more easy ways as Narayana Ganesh mentioned above....this method also can be more
precised if you want....
import java.io.;
import java.util.;
public class test2
{
public static void main(String[] args)
{
String bowler;
String name;
int score1 = 0, score2 = 0, score3 = 0;
int game = 0;
int average = 0;
String filename = "bowl1.txt";
File textfile = new File(filename);
try{
Scanner scan = new Scanner(textfile);
while (scan.hasNextLine()){
bowler = scan.nextLine();
System.out.println("\n" + bowler);
String text1 = "";
String text2 = "";
int index=0;
int length = bowler.length();
index = bowler.lastIndexOf(" ");
text1 = bowler.substring(0,index);
text2 = bowler.substring(index+1,length);
score1 = Integer.parseInt(text2);
length = text1.length();
index = text1.lastIndexOf(" ");
text2 = text1.substring(index+1,length);
text1 = text1.substring(0,index);
score2 = Integer.parseInt(text2);
length = text1.length();
index = text1.lastIndexOf(" ");
text2 = text1.substring(index+1,length);
text1 = text1.substring(0,index);
score3 = Integer.parseInt(text2);
System.out.println(score1);
System.out.println(score2);
System.out.println(score3);
System.out.println("Total:"+(score1 + score2 + score3));
}
}catch(FileNotFoundException e){};
}
}
I have a text file that I have to use in my program. I have already created
a file reader to display the contents of the file. However, I don't want to display all of the content but display the number of words.
For example, my file named database is a file that displays the priceof each individual and has four lines that display the name, age, activity and the price. I want to create a report which shows the total number of basketball players and total number of soccer players and then display the average price.
Here is my code so far:
String fileName = "database.txt";
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferReader = new BufferedReader(fileReader);
while ((line = bufferReader.readLine()) != null) {
}
}
How can I count and add the total values of basketball as well as soccer for the output as well as obtaining each fee and calculating the total and average?
You can the try the below code. You can split the lines from file with whitespace and use them. I have used an if condition in else part, because if any other type of sport comes in the file.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Player {
public static void main(String[] args) throws IOException {
int basketballCount = 0;
int soccerCount = 0;
double basketballFee = 0.0;
double soccerFee = 0.0;
BufferedReader read = new BufferedReader(new FileReader("database.txt"));
String line;
while ((line = read.readLine()) != null) {
String parts[] = line.split(" ");
if (parts[3].equals("basketball")) {
basketballCount++;
basketballFee = basketballFee + Double.parseDouble(parts[4]);
} else if (parts[3].equals("soccer")) {
soccerCount++;
soccerFee = soccerFee + Double.parseDouble(parts[4]);
}
}
System.out.println("Total Player: "+basketballCount + "\tTotal Fee: " + basketballFee + "\tAvg Fee:" + basketballFee/basketballCount);
System.out.println("Total Player: "+soccerCount + "\tTotal Fee: " + soccerFee + "\tAvg Fee:" + soccerFee/soccerCount);
}
}
You might want to take a look at String#split(). Essentially, the code will look like this:
String[] tokens = line.split(" ");
double value = Double.valueOf(tokens[4]);
String sport = tokens[3];
Then you can do whatever you want to those values. The official documentation for the method:
Splits this string around matches of the given regular expression.
This method works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array
Returns:
the array of strings computed by splitting this string around matches of the given regular expression
This code reads the file using Scanner and then finds average of basketball fee and soccer fee it is self explanatory if there is any please comment
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class StackOverflow
{
public static void main(String[] args) throws FileNotFoundException
{
Scanner sc = new Scanner(new File("database.txt"));
int basketball = 0;
int soccer = 0;
double basketfee = 0.0, soccerfee = 0.0;
while (sc.hasNextLine())
{
String line = sc.nextLine();
if (line.contains("basketball"))
{
basketball++;
String fee = line.substring(line.lastIndexOf(' '));
fee = fee.trim();
basketfee = basketfee + Double.parseDouble(fee);
}
else if (line.contains("soccer"))
{
soccer++;
String fee = line.substring(line.lastIndexOf(' '));
fee = fee.trim();
soccerfee = soccerfee + Double.parseDouble(fee);
}
}
System.out.println("Average fee for basketball is " + basketfee / basketball);
System.out.println("Average fee for soccer is " + soccerfee / soccer);
}
}
I'm working on an assignment in which I use scanners to read lines and tokens of a .txt file. I need to do some conversions and rearrange a few strings, which I have done using some helper methods. The problem is that the code is only working for every other line that it reads from the file. I think I may have messed something up somewhere in the beginning of the code. Any hints or tips on what I would need to modify? Here's what I have thusfar:
public static void main(String[] args) throws FileNotFoundException {
Scanner input = new Scanner(new File("PortlandWeather2013.txt"));
while (input.hasNextLine()) {
String header = input.nextLine();
System.out.println(header);
Scanner input2 = new Scanner(header);
while (input2.hasNextLine()){
String bottomHeader = input.nextLine();
System.out.println(bottomHeader);
String dataLines = input.nextLine();
Scanner linescan = new Scanner(dataLines);
while (linescan.hasNext()){
String station = linescan.next();
System.out.print(station+ " ");
String wrongdate = linescan.next();
String year = wrongdate.substring(0,4) ;
String day = wrongdate.substring(6);
String month = wrongdate.substring(4,6);
System.out.print(month + "/" + day + "/" + year);
double prcp = linescan.nextDouble();
System.out.print("\t "+prcpConvert(prcp));
double snwd = linescan.nextDouble();
System.out.print("\t " + snowConvert(snwd));
double snow = linescan.nextDouble();
System.out.print("\t" + snowConvert(snow));
double tmax = linescan.nextDouble();
System.out.print("\t" + tempConvert(tmax));
double tmin = linescan.nextDouble();
System.out.println("\t" + tempConvert(tmin));
}
}
}
}
public static double prcpConvert(double x){
double MM = x/1000;
double In = MM * 0.039370;
double rounded = Math.round(In * 10)/10;
return rounded;
}
public static double snowConvert(double x){
double In = x * 0.039370;
double rounded = Math.round(In * 10)/10;
return rounded;
}
public static double tempConvert(double x){
double celsius = x/10;
double fahrenheit = (celsius *9/5)+32;
double rounded = Math.round(fahrenheit *10)/10;
return rounded;
}
nextLine() doesn't just fetch the last line, it also advances a line. Before your second loop you are calling nextLine() twice causing you to advance two lines each iteration of the loop.
You can fix your problem by setting dataLines = bottomHeader instead of calling nextLine() again.