-1

I have implemented the following code which takes these values as input:-

3 6
CLICK 1
CLICK 2
CLICK 3
CLICK 2
CLOSEALL
CLICK 1

But for taking string input I tried nextLine() but it is not taking input in that case.If I use next() then it treats CLICK and 1 as two different strings and so I am getting ArrayIndexOutOfBoundsException as I am splitting the string and parsing it to int. What is the alternative to handling such inputs?

import java.util.*;
    
public class TweetClose {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int k = sc.nextInt();
        int open = 0;
        int a[] = new int[50];

        for (int i = 1; i <= n; i++) {
            a[i] = 0;
        }

        for (int i = 0; i < k; i++) {
            String s = sc.nextLine();
            if (s.equals("CLOSEALL")) {
                open = 0;
                for (int j = 1; j <= n; j++) {
                    a[j] = 0;
                }
            } else {
                String[] st = s.split(" ");
                int y = Integer.parseInt(st[1]);
                if (a[y] != 1) {
                    a[y] = 1;
                    open++;
                }
            }
            System.out.println(open);
        }
        sc.close();
    }
}
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
Sia Saxena
  • 21
  • 5
  • In addition to the issue with using `sc.nextLine()` after `sc.nextInt()` there are other possible causes of `ArrayIndexOutOfBoundsException` where array `a` is created with a fixed size and then indexes from non-validated user input are applied: `for (int i = 1; i <= n; i++)` or `for (int j = 1; j <= n; j++)` - if `n >= 50`; similar issue when parsing number after CLICK: `int y = Integer.parseInt(st[1]); if (a[y] != 1)`: if `y>=50` – Nowhere Man Feb 14 '21 at 15:27

2 Answers2

2

sc.nextInt() does not scan the carriage return symbol. You need to make sure to scan that before trying to parse the next input.

e.g.:

import java.util.*;

public class TweetClose {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.nextLine();
        int k = sc.nextInt();
        sc.nextLine();
        int open = 0;
        int[] a = new int[50];
        for (int i = 1; i <= n; i++) {
            a[i] = 0;
        }
        for (int i = 0; i < k; i++) {
            String s = sc.nextLine();
            if (s.equals("CLOSEALL")) {
                open = 0;
                for (int j = 1; j <= n; j++) {
                    a[j] = 0;
                }
            } else {
                String[] st = s.split(" ");
                int y = Integer.parseInt(st[1]);
                if (a[y] != 1) {
                    a[y] = 1;
                    open++;
                }
            }
            System.out.println(open);
        }
        sc.close();
    }
}
Domenico Sibilio
  • 1,189
  • 1
  • 7
  • 20
  • This works only if each line contains only one token. But the input has lines each with 1-2 tokens. – Stefan Feb 14 '21 at 15:23
  • Thanks @Domenico Siblio It resolved my issue. – Sia Saxena Feb 14 '21 at 15:23
  • The question was not properly formatted when I answered so there was no way to know if `3` and `6` are really inputted on the same line or 2 different lines. My impression is that all tokens are passed on a single line, if it is not the case then it's a simple matter of removing the extra `sc.nextLine()` between `n` and `k` declaration. Thanks for noticing. – Domenico Sibilio Feb 14 '21 at 15:25
  • @SiaSaxena, no problem! Since you're new to the website, I suggest you to mark my answer as accepted in order to close the thread. Have a nice day. – Domenico Sibilio Feb 14 '21 at 15:27
2

The problem caused by using nextLine(). You should use next() instead because you want to process the next token.

After processing all tokens, the final line-break of the current line is still in memory. nextLine() returns that line break "\n". Then you process it:

String[] st = s.split(" ");
int y = Integer.parseInt(st[1]);

The split function returns an array with only one element (the "\n"), therefore you cannot parse st[1]. There is no such element, only st[0] exists.

It will work with next() instead of nextLine() because next() skips over the line break and proceeds with the next token of the next line.

This is a very common mistake because there is no nextString() function.

Stefan
  • 1,789
  • 1
  • 11
  • 16