0

I'm trying to create a code that prints "VALID ENTRY" if the input begins with "Today" and ends with "MLIA" (case doesn't matter). If it doesn't, then it prints "INCORRECT FORMATTING, TRY ANOTHER SUBMISSION". For some reason, the program keeps giving me an out-of-bounds error and I can't figure out why.

When I changed the substring code to sub.substring(0,1) to test it still gave me an error, so that is not the problem. I also tried adding the char value for each letter to determine what the word was but that didn't work either.

public class submit{
   public static void main(String[] args) throws IOException{

   Scanner scanner = new Scanner(new File("submit.txt"));

   int trials = scanner.nextInt();
   int total = 0;

   for(int x = 0; x <= trials; x++){
       String sub = scanner.nextLine();
       sub = sub.toLowerCase();
       if(sub.substring(0,5) == "today") //I only have it set up to find "today"
         System.out.println("VALID ENTRY");
       else
         System.out.println("INCORRECT FORMATTING, TRY ANOTHER SUBMISSION");

      }  
   }//end of main
}//end of class

Input:

5  
ToDAY, I went to school. mlia  
Hehehe today mlia this shouldn't work  
Today, I went to a programming contest. Hehe. MLIA  
TODAYMLIA  
T0day is a brand new day! MLIA  

Expected output should be:

VALID ENTRY  
INCORRECT FORMATTING, TRY ANOTHER SUBMISSION  
VALID ENTRY  
VALID ENTRY  
INCORRECT FORMATTING, TRY ANOTHER SUBMISSION  

Actual output:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 5  
    at java.lang.String.substring(String.java:1963)   
    at submit.main(submit.java:15)
Sebastian D'Agostino
  • 1,279
  • 2
  • 24
  • 35
jannCann
  • 3
  • 6
  • 2
    Possible duplicate of [Scanner is skipping nextLine() after using next() or nextFoo()?](https://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-or-nextfoo) – resueman Sep 18 '19 at 20:09
  • 2
    if(sub.substring(0,5) == "today") wrong if(sub.substring(0,5).equals("today")) correct – muasif80 Sep 18 '19 at 20:13
  • If you call `nextLine` immediately after `nextInt`, it will usually return an empty `String`. This is because the newline after the number hasn't been read yet. You need to call a `nextLine` after the `nextInt` to advance to the next line after the number. – resueman Sep 18 '19 at 20:13
  • Yes @zachary, but even when I change the index it still gives me the same error. Plus each input is longer than 5 characters. – jannCann Sep 18 '19 at 20:14
  • all the input string are more than 5 in length. – muasif80 Sep 18 '19 at 20:15
  • substring(0, 5) is correct as endIndex is exclusive https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int,%20int) – muasif80 Sep 18 '19 at 20:17
  • @resueman Can you give me an example? I'm having trouble understanding what you're trying to say. – jannCann Sep 18 '19 at 20:20

2 Answers2

0

There are two problems with the code. First, you should compare Strings using equals, not ==. Otherwise it can return false even for identical Strings.

Second, nextLine will read from the Scanner up until after the next newline. But nextInt only will read up until before that newline, so your first call to nextLine simply advances the Scanner by one character and returns an empty String. You need to call an extra nextLine after nextInt to advance onto the next line after your integer. For more information, see this question.

So you should make the following changes to your code:

Scanner scanner = new Scanner(new File("submit.txt"));

int trials = scanner.nextInt();
scanner.nextLine(); //Add this line, to consume the newline character after "5"
// alternatively, you could replace both of the above lines with this:
// int trials = Integer.parseInt(scanner.nextLine());
int total = 0;

for(int x = 0; x <= trials; x++){
   String sub = scanner.nextLine();
   sub = sub.toLowerCase();
   if(sub.substring(0,5).equals("today")) //compare strings using equals, not ==
     System.out.println("VALID ENTRY");
   else
     System.out.println("INCORRECT FORMATTING, TRY ANOTHER SUBMISSION");

}
resueman
  • 10,389
  • 10
  • 29
  • 43
0

You can use the following code instead.

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class Submit {
    public static void main(String[] args) throws IOException {

        Scanner scanner = new Scanner(new File("submit.txt"));

        int trials = scanner.nextInt();
        scanner.nextLine();
        int total = 0;

        for (int x = 0; x < trials; x++) {

            String sub = scanner.nextLine();
            sub = sub.toLowerCase();
            System.out.print(sub + " -> ");
            if (sub.startsWith("today")) // I only have it set up to find "today"
                System.out.println("VALID ENTRY");
            else
                System.out.println("INCORRECT FORMATTING, TRY ANOTHER SUBMISSION");

        }
        scanner.close();
    }// end of main
}// end of class

You can use the startsWith and nextLine needs to be called after nextInt because nextInt does not read the newline character and keeps the curson on the same line after the int 5 is read. So you get that error that you are facing.

When you put an extra nextLine() it actually moves to next line.

After that you have only 5 lines to read and you don't need <= otherwise it will throw error in the end again.

So make is < only

And startsWith() is good if you only have to check the beginning and if you want to check end too then there is a method endsWith() as well

Also the string needs equals for matching with string literals if you want to use the equality.

muasif80
  • 2,978
  • 2
  • 24
  • 36