Search code examples
javastringsplit

Comma Separated User input in java


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));
}

Solution

  • 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));
        }