1

I want to provide the series of inputs of my program from a text file so that I do not have to give input time and again, how can I do this using "javac"?

I used to do this in C/C++ Programs and it looked like as far as I remember gcc <sample.txt> filname.exe and it was called batch processing as told by my professor.

Is there any way to do the same with javac or by using some tweak in VS Code so that I do not have to give input from keyboard every time I run the program?

Thank You!

  • Yes, just use https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Scanner.html#%3Cinit%3E(java.io.File) – k314159 Mar 29 '21 at 16:32
  • If you're using this just to test your code, you can just hard-code the input into the program itself rather than taking interactive input for the time being. – cMcNerlin Mar 29 '21 at 16:34
  • So you want your code to contain: `Scanner s = new Scanner(System.in);` but for `s.nextLine()` you want the value to come from a text file rather than the standard input. Is that correct? – Abra Mar 29 '21 at 16:52
  • @k314159 I read it but I could not understand how can I use text file can you please help me in understanding>? – huzaifa imran Mar 29 '21 at 17:24
  • @cMcNerlin I used to do that But code consists of three classes I can't really hardcore all that stuff with all different possibilities to be evaluated Like number of inputs sentinel values e.t.c. After it i'd have to replace everything as well! – huzaifa imran Mar 29 '21 at 17:26
  • @Abra Precisely, Like I dont have to enter it time and again but instead it automatically fetches from text file! – huzaifa imran Mar 29 '21 at 17:26
  • `Scanner in = new Scanner(new File("input.txt"));` – k314159 Mar 29 '21 at 17:26
  • @k314159 Got it, Thanks So as far as I am getting, File is a class whose object's constructor takes the filename Does that mean .txt file has to be in same folder as .java file? – huzaifa imran Mar 29 '21 at 17:29
  • It should be in the directory from which you run your program. Which directory that is, depends on a lot of things. You'll need to read documentation of your IDE, if you're using one, or just by trial and error. – k314159 Mar 29 '21 at 17:31
  • Got it, So that means without changing the Scanner class its impossible to provide the input by a .txt file by using some javac command unlike gcc? – huzaifa imran Mar 30 '21 at 07:44
  • You can redirect stdin with java just like with any other command. `java MyApp < input.txt`. – k314159 Mar 30 '21 at 08:05

2 Answers2

1

If you want to be able to run the same code, unchanged, for either getting user input via standard input or via a file, I suggest defining a "system" property as a flag to determine where user input comes from, depending on whether the property is defined or not.

import java.io.IOException;
import java.nio.file.Paths;
import java.util.Scanner;

public class Testings {
    public static void main(String[] args) throws IOException {
        String redirect = System.getProperty("REDIRECT");
        Scanner scanner;
        if (redirect != null) {
            scanner = new Scanner(Paths.get("", args));
        }
        else {
            scanner = new Scanner(System.in);
        }
        if (scanner.hasNextLine()) {
            System.out.println(scanner.nextLine());
        }
        if (redirect != null) {
            scanner.close();
        }
    }
}

If you want input from a file, rather than from standard input, use the following command to run the code.

java -DREDIRECT Testings path/to/file.txt

If you want input from the user, via the keyboard then remove -DREDIRECT, i.e.

java Testings

Since you are not getting input from the file, no need to provide a path.

Note that if you are using an IDE, then it should provide the ability to define a "system" property as above. Also note that the property name can be anything. I simply (and arbitrarily) chose REDIRECT. Remember though, that it is case sensitive.

Alternatively, you can redirect System.in.

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;

public class Testings {
    private static void redirect(String[] args) throws IOException {
        Path path = Paths.get("", args);
        InputStream is = Files.newInputStream(path);
        System.setIn(is);
    }

    public static void main(String[] args) throws IOException {
        String redirect = System.getProperty("REDIRECT");
        Scanner scanner;
        if (redirect != null) {
            redirect(args);
        }
        scanner = new Scanner(System.in);
        if (scanner.hasNextLine()) {
            System.out.println(scanner.nextLine());
        }
    }
}

Regarding the file that you use for input, the path to the file can be either relative or absolute. If it is relative, then it is relative to the current working directory which is the value returned by the following code:

System.getProperty("user.dir");

Alternatively, you could make the file a resource which would mean that the path is relative to the CLASSPATH.

Abra
  • 19,142
  • 7
  • 29
  • 41
0

Once you've created a new Scanner using System.in, you can send data to that program in at least three ways.

Example code

Here's an example bit of code. It reads three lines of text from System.in, then prints all three lines.

import java.util.Scanner;

public class SystemInExample {
    public static void main(String[] args) throws Exception {
        Scanner scanner = new Scanner(System.in);

        String one = scanner.nextLine();
        String two = scanner.nextLine();
        String three = scanner.nextLine();

        System.out.println("one: " + one);
        System.out.println("two: " + two);
        System.out.println("three: " + three);
    }
}

Providing input in three ways

  1. Here's a sample run where I typed in three lines of text, then it parroted the lines back out.
    aaaaaaa
    bbbbbbb
    ccccccc
    one: aaaaaaa
    two: bbbbbbb
    three: ccccccc
    
  2. Here's a variation using a pipe:
    • use a text file ("input.txt") which has three lines of text
      % cat input.txt 
      one one one
      two two two
      three three three
      
    • use cat to send the contents of that file to a pipe
    • the piped output goes to the Java program, which I ran using "java" to compile+run in one step – no "javac"
      % cat input.txt | java SystemInExample.java
      one: one one one
      two: two two two
      three: three three three
      
  3. Here's another variation using a redirect:
    • use the same text file
    • run the program (again, JEP 330-style)
    • use < to direct the file contents to stdin for the program
      % java SystemInExample.java < input.txt 
      one: one one one
      two: two two two
      three: three three three
      

The above variations should work fine on mac/unix/linux. If you're using Windows, this probably wouldn't work without modifications.

Kaan
  • 5,434
  • 3
  • 19
  • 41