Search code examples
javajsonjava-8java.util.scannerstringbuilder

Accepting formatted Json (multi-line) input from user in a Java console app with Scanner (all lines not being read)


I have a scenario where I need to take formatted Json (multi-line) as an input and do something with it. I figured doing it in a simple console app would be good since it is just a tool I am creating and want it to be able to be ran locally. If I should be reading the Json from a file instead please let me know.

The plan is to have the user paste something like this into a console application and then type "exit".

    {
       "section1":{
          "line1":0.3456,
          "line2":{
             "line3":45345,
             "line4":67567
          },
          "section2":{
             "line6":867867,
             "line7":0.16767
          },
          "section3":{
             "line9":9977,
             "line10":0.76867
          },
          "array1":[
             {
                "ghjf":"1111",
                "ggeeaaa":678769,
                "ghj":0.6799789
             }
          ]
       }
    }
exit

A couple of things are happening:
1. The first { is not being recognized so I need to manually insert it.
2. Several lines are not being read... i.e. "line1" is getting skipped and many more.

Here is my code:

System.out.println("Enter a valid JSON string: ");

Scanner scanner = new Scanner(System.in);

StringBuilder sb = new StringBuilder();

while (!scanner.nextLine().equals("exit")) {
    sb.append(scanner.nextLine());
}

sb.insert(0, "{");

String formattedJson = sb.toString()
        .replaceAll("\\t","").replaceAll("\\s", "");


 // Do something with formattedJson further in code...

Solution

  • You are calling scanner.nextLine() twice, but only use the value once.

    Try declaring it as a variable and only calling nextLine() once:

    Scanner scanner = new Scanner(System.in);
    
    StringBuilder sb = new StringBuilder();
    
    String line;
    while (!(line = scanner.nextLine()).equals("exit")) {
        sb.append(line);
    }
    

    As a result, you probably won't need (should remove) this:

    sb.insert(0, "{");