Below are the inputs:
Event Name, Date, No. of attendees
Catering party, 01/01/2018, 100
Wedding,24/01/2018,500
Bike Stunts show, 06/01/2018, 300
Below is the code:
public static void main(String[] args) throws ParseException {
//SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List<Event> events = new ArrayList<>();
for (int i = 0; i < n; i++) {
sc.next();
//String line=sc.nextLine();
String parts[] = sc.nextLine().split(", ");
//StringTokenizer st = new StringTokenizer(line,", ");
//int j=0;
//while(st.hasMoreTokens()) {
//System.out.println(st.nextToken());
//parts[j]=st.nextToken();
//j++;
//}
//System.out.println(j);
//String[] inputs = sc.nextLine().split(", ");`
for (String data : parts) {
System.out.println(data);
}
String name = parts[0].trim();
String date = parts[1].trim();
String attendee = parts[2].trim();
int count = Integer.parseInt(attendee);
events.add(new Event(name, date, count));
}
}
Below is the Error:
3Number of inputs
Catering party, 01/01/2018, 100
party
01/01/2018
100
Wedding, 24/01/2018, 500
24/01/2018
500
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at Main.main(Main.java:74)
I have tried both String Tokenizer and split method but as you can see in the error that I am not able to take the input in correct format. Please help me to know what is wrong in my code.
Hello Everyone! After getting stuck with sc.next() and sc.nextLine() I have used BufferedReader to take the input. And it is working below is the code:
for (int i = 0; i < n; i++) {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line=reader.readLine();
String parts[] = line.trim().split(",");
for (String data : parts) {
System.out.println(data);
}
name = parts[0].trim();
date = parts[1].trim();
attendee = parts[2].trim();
count = Integer.parseInt(attendee);
events.add(new Event(name, date, count));
}
You may have noticed that, from your debug logs, you're not getting the correct output even before the IndexOutOfBoundsException. This is due to the sc.next(); that you added at the beginning of the for loop. This is also the reason behind the exception in the second iteration.
What is actually happening
The compiler is reading the first non-space seperated integer characters through sc.nextInt();
Then, in the for loop, you are reading the next non-space seperated string through sc.next();. In your case, that's the word "Catering".
After that, the compiler is reading the rest of the line as "party, 01/01/2018, 100" and operating on it. This is why you are only getting the word "party" in the sysout rather than "Catering party".
The same happens for the next line of input, except this time the entirety of "Wedding," is considered a single sc.next() so you end up with "24/01/2018, 500" and an IndexOutOfBoundsException.
The only reason the first line worked is because it had two words in the first argument so it didn't affect the split array size.
Solution
I would recommend you try to fix it yourself before reading this next part. Consider using the debugger! It's a very helpful tool.
after reading the initial number input sc.nextInt() you should add sc.nextLine(); so that the compiler understands that the previous line is finished and the next read should be on a new line.
You should remove sc.next(); as this accomplishes nothing. (I'm guessing you added this to try and solve the issue where the compiler wasn't reading the next line as mentioned previously).
Finally, I would recommend you split on , rather than , since you're trimming the strings anyway.
#alankar's solution
I have used BufferedReader and now I am able to take input.
for (int i = 0; i < n; i++) {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String line=reader.readLine();
String parts[] = line.trim().split(",");
for (String data : parts) {
System.out.println(data);
}
name = parts[0].trim();
date = parts[1].trim();
attendee = parts[2].trim();
count = Integer.parseInt(attendee);
events.add(new Event(name, date, count));
}
try to remove white spaces before splitting your input, to make sure there is no white spaces that can affect your separator, also you have to check if the user has entered three fields separated by comma. Here's an example:
public static void main(String[] args) throws ParseException {
//SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
List<Event> events = new ArrayList<>();
for (int i = 0; i < n; i++) {
sc.next();
//String line=sc.nextLine();
String parts[] = sc.nextLine().trim().split(",");
if (parts.length != 3) {
throw new IllegalArgumentException("Error: Input must have 3 parts separated by comma");
}
String name = parts[0];
String date = parts[1];
String attendee = parts[2];
int count = Integer.parseInt(attendee);
events.add(new Event(name, date, count));
}
}
Related
I am learning java program. I have a question to solve . the question is
enter the no . of people:
enter the product_name, price, stock_available:
total amount is price * no. of people
if the stock available is less than the no of people the print value 0
Example:
**input:**
no . of people : 3
product_name, price, stock_available: book, 100, 3
**output:** 300
public class Product {
public static void main(String args[]) {
Scanner sc=new Scanner(System.in);
System.out.println("Enter the no . of people:");
int people=sc.nextInt();
String[] string = new String [3];
System.out.println("Enter the product_name, price, quantity_available:");
for (int i = 0; i < 3; i++)
{
string[i] = sc.nextLine();
}
int quantity=Integer.parseInt(string[2]);
int price=Integer.parseInt(string[1]);
if(people<=quantity) {
System.out.println("Total amout is:"+(price*people));
}
else
{
System.out.println("value is "+0);
}
}
}
console error:
Enter the no . of people:
3
Enter the product_name, price, quantity_available:
book
30
Exception in thread "main" java.lang.NumberFormatException: For input string: "book"
How to solve this error and how to do better way using oops concept ?
For Loop I always prefer to read input using next() .
Using next() will only return what comes before the delimiter (defaults to whitespace). nextLine() automatically moves the scanner down after returning the current line.
As you were using sc.nextLine() this may one reason you were getting java.lang.NumberFormatException.
Try as sc.next(); to read your input
Your problem is you are using :
for (int i = 0; i < 3; i++)
{
string[i] = sc.nextLine();
}
this sc.nextLine() while taking input. Now the problem is sc.nextLine() reads a line until '\n' or enter is encountered. Now, for the first cycle in for loop it it putting a '\n' in the buffer. Because nextLine() stop taking input while '\n' encountered. So, In the next cycle the value of string[1] = '\n'. And when you try to parse this to an Integer then an error occurs. Because this is not an Integer.
Try this:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the no . of people:");
int people = sc.nextInt();
String[] string = new String [3];
System.out.println("Enter the product_name, price, quantity_available:");
for (int i = 0; i < 3; i++)
{
string[i] = sc.next();
}
int price = Integer.parseInt(string[1]);
int quantity = Integer.parseInt(string[2]);
if(people <= quantity) {
System.out.println("Total amount is: "+ (price*people));
}
else
{
System.out.println("value is: "+0);
}
}
You can use an extra sc.nextLine() just before the loop...
sc.nextLine() ----> add this line
for (int i = 0; i < 3; i++)
{
string[i] = sc.nextLine();
}
when you press enter after getting the value of people... your string[] array takes a value in its 0 index position. So the nextLine scans only 2 values from the console and then throws an exception.
On that time your string[] values are = {"", "NAME", "PRICE"}
And you are trying to parse a string value (NAME) to int
According to your input style, your code does not serve your purpose.
Problem:
Case 1: You tried to input something like:
product_name, price, stock_available: book, 100, 3
But in your code, using for loop you tried to get 3 string values.
for (int i = 0; i < 3; i++)
{
string[i] = sc.nextLine();
}
So, after first input, when you press enter without any input, it throws java.lang.NumberFormatException: For input string: ""
Case 2: nextLine() scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present. And this is the reason, you may get this exception.
when the loop executes, string[0]'s value will be ""/blank string, which it gets from the buffered line separator. string[1]'s value will be your first string input(product_name).
so, when you tried to parse it as int, it threw number format exception.
Solution:
Case 1. If you want to take input in one line then, do not use for loop. Get input as a string and parse it to get your values.
String[] string = new String[3];
String inputString = null;System.out.println("Enter the product_name, price, quantity_available:");
inputString=sc.next();
string=inputString.split(",");
String product = string[0];
int quantity = Integer.parseInt(string[2]);
int price=Integer.parseInt(string[1]);
Case 2. If you do not solve the buffered line separator issue, then you should use next() method to take input.
This is very simple application. So, oop concept is not necessary for the current context.
Write a method called UploadData to do this task. Choose the appropriate parameters and return type.
Input File Format:
Month Day Year Output
Sample Input File:
January 10 2018 236.9 January 11 2018 267.6 January 12 2018 278.1
Then I have to write another method that displays what has been read in .
This is what I have so far..
public static ArrayList<String> uploadData() throws IOException
{
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter the name of the file");
String fileName = keyboard.nextLine();
ArrayList<String> List = new ArrayList<String>();
File myFile = new File(fileName);
Scanner scan = new Scanner(myFile);
while (scan.hasNextLine()) {
String n = scan.nextLine();
scan.next();
System.out.println(scan.next());
}
ArrayList<String> end = new ArrayList();
return end;
}
I think you have to use a Regular Expression to split the values in a line. Try the following code:
public static ArrayList <String> uploadData() throws IOException {
//this pattern can separate the string in multiple dates base on format of your example input file
Pattern pattern = Pattern.compile("(\\w+ \\d{1,2} \\d{4} \\d{3}\\.\\d{1})");
Scanner keyboard = new Scanner (System.in);
System.out.println("Please enter the name of the file");
String fileName= keyboard.nextLine();
// dateList is a better name than List
ArrayList <String> dateList = new ArrayList <String>();
File myFile= new File(fileName);
Scanner scan = new Scanner (myFile);
while(scan.hasNextLine()) {
String n = scan.nextLine();
Matcher matcher = pattern.matcher(n);
// each date thats matches the pattern will be added to the list
while(matcher.find()) {
dateList.add(matcher.group());
}
}
for (String dateString: dateList) {
System.out.println(dateString);
}
return dateList;
}
This semi-pseudocode should help get you on the right track without me writing it for you. This method only works if the data is always perfectly structured like your sample input. It also may not be the best way :) but you can figure out any improvements that could be made.
uploadData
ArrayList<Data> dataToPrint = ....
while(input.nextLine)
String line = input.getline
String[] dataArray = line.split(" ") //split on space
count = 1
Data d;
for(int i=0; i<dataArray.length; i++)
if count == 1
d = new Data
d.setMonth(dataArray[i])
if count == 2
d.setDay(...)
if count == 3
d.setYear(...)
if count == 4
d.setAmount(...)
dataToPrint.add(d)
count = 1
Data Class
Data
String month
int day
int year
float amount
import java.util.Scanner;
class HistogramChart
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the population of data: ");
int populationOfData = scan.nextInt();
System.out.println("Please enter data separated by spaces: ");
String data = scan.next();
int indexWhiteSpace = data.indexOf(" ");
int[] dataArray = new int[populationOfData];
int tempInt = 0;
for(int index = 0; index < populationOfData; index++)
{
String tempString = data.substring(0, indexWhiteSpace);
data = data.substring(indexWhiteSpace+1, data.length());
tempInt = Integer.parseInt(tempString);
dataArray[index] = tempInt;
indexWhiteSpace = data.indexOf(" ");
}
System.out.println(dataArray[0]);
}
}
I realize there's nothing yet to print out the entire array, as i'm just trying to get it to print anything, but this is continually printing the following errors:
"Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(String.java:1954)
at HistogramChart.main(HistogramChart.java:22)
"
I cannot figure out why this is saying this.
Please help!
Why not using split ?
class HistogramChart {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter data separated by spaces: ");
String data = scan.nextLine();
String tmpDataArray[] = data.split(" ");
int dataArray[] = new int[tmpDataArray.length];
for (int i = 0; i < dataArray.length; ++i) {
dataArray[i] = Integer.parseInt(tmpDataArray[i]);
}
}
If I remember correctly, using
String data = scan.next();
Like you're doing, you will just scan a single element. Try using scan.nextLine() so that it takes the whole line, and then split by spaces so you get an array of your data. And the problen it is actually giving you is because you look for indexOf(" ") but since you're not reading a full line, that nevers happens and you get a -1. When you try to look for a substring with the index -1, then you get that error.
I'm trying to read from a file containing names and doubles, this would be easy if it was first name, last name then the doubles, but some of the lines have a middle initial and some have just one name.
Like this:
Hancock John 40.00 9.75
Light Karen L 40.00 9.60
Bob 12.02 42.90
and so on
I'm putting the names into a string array and the numbers into a 2d array.
So how would I separate those data types?
EDIT:
I was trying this at first
import java.io.*;
import java.text.*;
import java.util.*;
public class JEdwards11
{
public static void main(String[] args) throws Exception
{ PrintWriter outFile = new PrintWriter("H:/Java/program11.out");
String filename = "H:/Java/program11.dat", line, fullname;
StringTokenizer st;
Scanner inFile = new Scanner(new FileReader(filename));
int ctr = 0, i = 0, k = 0;
String [] names = new String [30];//print vertically
double [][] money = new double [7][30];//short across, long down
//hours worked, hourly rate, gross pay, net pay, fed, state, union
//while(inFile.hasNext())
for(i=0; i< names.length; i++)
{
if(inFile.hasNextDouble())
{money[1][i] = inFile.nextDouble();
money[2][i] = inFile.nextDouble();}
else
names[i] = inFile.next();
}
/*while(inFile.hasNext())
{line = inFile.nextLine();
st = new StringTokenizer(line);
names[i]=st.nextString;
money[1][i] = st.nextDouble();
money[2][i] = st.nextDouble();*/
for(i=0;i<names.length;i++)
for(i=0; i<names.length; i++)
System.out.println("name = " + names[i] +" money1 = "+money[1][i] +" money2= "+money[2][i]);
inFile.close();
outFile.close();
}
}
which did not work at all. Since then I've searching Google and re-reading my java book. Sorry for the formatting, it's not being cut/paste friendly and last time I hit enter it posted before I was ready :(
You may have followed another approach. Anyway I give you one easy trick to solve it with Scanner, just add tokens to a buffer until digits are encountered, then assign it to the name array.
Again, your if-else block is erroneous since per iteration either if-part or the else-part will be executed. Try something like this, it will definitely solve your problem :
for (i = 0; i < names.length; i++) {
StringBuffer sbr = new StringBuffer();
while (inFile.hasNext("[a-zA-Z]+")) {
sbr.append(inFile.next() + " ");
}
names[i] = sbr.toString().trim();
if (inFile.hasNextDouble()) {
money[1][i] = inFile.nextDouble();
money[2][i] = inFile.nextDouble();
}
}
Are you familiar with Scanner?
http://www.tutorialspoint.com/java/util/java_util_scanner.htm
There's a link, or just google Java.Util.Scanner.
I would init a Java.Util.Scanner with the file text, then use calls to hasNextDouble() to determine if next token is a double. If so, scan it with nextDouble, otherwise treat the next token as part of a name.
//psuedo code
Scanner s; // init with file
while ( s.hasNext() )
{
if ( s.hasNextDouble() )
{
double d = s.nextDouble();
// add to array
}
else
{
String name = s.next();
// add to names
}
}
I'm doing an school exercise and I can't figure how to do one thing.
For what I've read, Scanner is not the best way but since the teacher only uses Scanner this must be done using Scanner.
This is the problem.
The user will input text to an array. This array can go up to 10 lines and the user inputs ends with an empty line.
I've done this:
String[] text = new String[11]
Scanner sc = new Scanner(System.in);
int i = 0;
System.out.println("Please insert text:");
while (!sc.nextLine().equals("")){
text[i] = sc.nextLine();
i++;
}
But this is not working properly and I can't figure it out.
Ideally, if the user enters:
This is line one
This is line two
and now press enter, wen printing the array it should give:
[This is line one, This is line two, null,null,null,null,null,null,null,null,null]
Can you help me?
while (!sc.nextLine().equals("")){
text[i] = sc.nextLine();
i++;
}
This reads two lines from your input: one which it compares to the empty string, then another to actually store in the array. You want to put the line in a variable so that you're checking and dealing with the same String in both cases:
while(true) {
String nextLine = sc.nextLine();
if ( nextLine.equals("") ) {
break;
}
text[i] = nextLine;
i++;
}
Here's the typical readline idiom, applied to your code:
String[] text = new String[11]
Scanner sc = new Scanner(System.in);
int i = 0;
String line;
System.out.println("Please insert text:");
while (!(line = sc.nextLine()).equals("")){
text[i] = line;
i++;
}
The code below will automatically stop when you try to input more than 10 strings without prompt an OutBoundException.
String[] text = new String[10]
Scanner sc = new Scanner(System.in);
for (int i = 0; i < 10; i++){ //continous until 10 strings have been input.
System.out.println("Please insert text:");
string s = sc.nextLine();
if (s.equals("")) break; //if input is a empty line, stop it
text[i] = s;
}