How to run a program on standard input? - java

I've created an implementation of a Sokoban-solver and the code is currently looking like this (not going to post all the code):
public Sokoban() throws Exception{
myList = new ArrayList<Integer>();
file = new File("C:/Users/joaki/Desktop/sokoban/readin.txt");
sc = new Scanner(file);
sc.reset();
List<String> lines = new ArrayList<>();
while (sc.hasNextLine()) {
line = sc.nextLine();
As you can see I'm just using the filepath to be able to read the file with a scanner, but according to my assignment, it should be looking like:
To be more concrete if "map1.txt" is a file with a sokoban map your
agent program "agent" will get map1.txt sent to in on standard input.
Under unix/linux this corresponds to running the program like
agent < map1.txt
I don't understand really what they mean, am I supposed to run the program from the command-line argument or from the cmd?

Instead of the program reading a file, it should read them from user input - so yes, you should run the program from the command line. This means your program should get the input from System.in, not open a file directly:
sc = new Scanner(System.in);

When creating the Scanner use this:
sc = new Scanner(System.in);
It will tell the scanner to read from the default input.

Related

Getting Output from Continuous (Unending) Terminal Programs in Java

Basically I'm running a program that takes continuous input. It doesn't end until you input an "#" symbol and press enter. I am wondering how I can read the output from this program, given that there is currently (what I have inferred is) a "readLine() block" when I try to get the BufferedReader content. Current code is below. I've done it with and without the while loop, and either way the program never reaches an end point, indicating to me it is the readLine() that is the problem.
An example of the program is something like
input a number:
2
You input 2
input a number:
3
You input 3
input a number:
#
exit
That isn't the program, but the basic gist of what it is and how it acts. I need to get every bit of that output. Input is another story; consider it irrelevant to the question for now, as I'm not even there just yet.
My code is below.
ProcessBuilder pb = new ProcessBuilder(cmd);
Process p = pb.start();
BufferedReader terminalOutput = new BufferedReader( new InputStreamReader(p.getInputStream()) );
BufferedWriter terminalInput = new BufferedWriter( new OutputStreamWriter(p.getOutputStream()) );
String line = "";
String s = "";
int count = 0;
line = terminalOutput.readLine();

java.util.Scanner: wait for input

I use java.util.Scanner to read the commands from the console.
try
{
ICommand cmd = cmdReader.ReadCommand();
cmd.Execute(conn);
}
catch(MyException ex)
{
// print a message about unknown command
continue;
}
Where ReadCommand is implemented as follows:
try (Scanner scanIn = new Scanner(System.in))
{
if (!scanIn.hasNextLine()) return null;
line_ = scanIn.nextLine();
ICommand command = parser_.ParseCommand(line_);
return command;
}
In the first iteration code works fine, I write something invalid (not a command), the code prints a warning and continues. But other iterations return null here if (!scanIn.hasNextLine()) return null; even if I write something in a console. Looks like java.util.Scanner doesn't see the input. Am I doing something wrong? And how then I can wait for the user input (don't want to use the cycle with sleep)?
You should not create a new Scanner instance each time you call ReadCommand. Create one and reuse it while reading input.
From the documentation:
When a Scanner is closed, it will close its input source if the source implements the Closeable interface.
So, your System.in stream is closed after you read the first input.
See also Java Scanner does not wait for input

Java scanner not working

This CSV reader which also checks the validity of an email address and password through the use of the map tool.
import java.io.*;
import java.util.*;
public class CSVReaders{
public static void run(String[] args) throws Exception {
Map<String, String> emailPasswordMap = new HashMap<String, String> ();
BufferedReader CSVFile =
new BufferedReader(new FileReader("testa453.csv"));
String dataRow = CSVFile.readLine();
while (dataRow != null){
String[] dataArray = dataRow.split(",");
emailPasswordMap.put (dataArray[0], dataArray[1]);
dataRow = CSVFile.readLine();
}
CSVFile.close();
//Scanner in = new Scanner(System.in);
//String email = in.nextLine();
//String password = in.nextLine();
String password = ("raj45");
String email = ("rakhter#bluebell.org");
if (password.equals (emailPasswordMap.get (email))) {
System.out.println ("The entered email and password are valid");
}
else {
System.out.println ("The entered email and password are invalid");
}
}
}
The problem which I am getting is that upon runing when i change the '//' over to the string password and email and attempt to use the scanner which I have included the program 'runs' but console window does not appear and I have to force stop the program to stop it running. Whilst using it as I have shown here it works perfectly. Previously I had an error with the scanner that related to static and non-static variables. I have looked them up and attempted to use instance variables but to little success.
Is the way in which I have declared the scanner wrong or can I not use Mapping in conjuction with the scanner?
EDIT: I am currently using BlueJ on Mac since I am reasonably new to java programming. And yes it does work as I have quoted it, it only stops working when I try to use the scanner.
Is the way in which I have declared the scanner wrong or can I not use Mapping in conjuction with the scanner?
The Scanner declaration appears to be correct. No, there is no restriction prohibiting the simultaneous use of any two parts of the Java standard library. So it is perfectly okay to use Map and Scanner together.
At current, the SO community's best guess is that you are using an IDE (like eclipse) that has a built-in console window/view. Under this assumption, it is assumed that you expect a black terminal/cmd window to open, however in most IDEs this is not the case. In eclipse the "console view" is where you will do your input. In Netbeans this will be the output window.

Java: always receive NoSuchElementException when use Scanner

I have this simple code:
public class Example {
public Example() {
Scanner scanner = new Scanner(System.in);
int row = scanner.nextInt(); // exception at this line
scanner.close();
}
public static void main(String[] args) {
Example ex1 = new Example(); // this line successfully operate
Example ex2 = new Example(); // exception : no such element exception at above line
}
}
I don't know why I always receive this Exception, when code run to ex2.
The problem is because you close the Scanner which in turn closes the underlying InputStream (in this case stdin). When you try to use stdin in again the Scanner is unable to retrieve any data because stdin has been closed.
If running directly from the commandlne then the correct way to provide access to stdin is to use the Console class. The console class provides a Reader wrapped around stdin that has a no-op close method. eg.
public class Example {
public Example() {
Scanner scanner = new Scanner(System.console().reader());
// note change on above line
int row = scanner.nextInt();
scanner.close();
}
}
Note, if you access stdin other than via the Console class then you'll likely cause problems for yourself. And if you invoke your java program other than directly from the command line then you will not get access to the console. For instance, the following will invokations cause problems.
echo 2 3 | java Example
or
Process p = new ProcessBuilder("java", "Example").start();
// write data to process
You Should add if(Scanner.hasNext()) before invoking scanner.nextInt();
You have the exception because no int found to be read.

how to handle a command-line input like "java.exe program < s1.in"

I know how to use string args to get the input from the command-line, and it is working fine with input = args[0] where my input is java.exe program s1.in
But I need to run a compare program in terminal. So my input must have the "<" symbol. However, then I can't get my input values using input = args[1]. When I type this in, the args.length become 0. Why does this happen?
As an aside, does anyone know how to best search for this kind of term in google? Itthink google does not recognize "<" in the search entry.
Thank you
It's because when you use xyzzy <inputfile, your shell runs xyzzy and "connects" that file to your standard input. It then expects you to read that standard input to get your data - you never see the argument because it's removed from the command line (or, more likely, never added to your argument list).
That's why many programs will process a file if given, otherwise they'll read their data from standard input. And that's exactly what you need to do here.
For doing this, you'll probably want something like:
import java.io.*;
class Test {
public static void main(String args[]) {
InputStreamReader inp = null;
Boolean isStdIn = false;
try {
if (args.length > 0) {
inp = new InputStreamReader(new FileInputStream(args[0]));
} else {
inp = new InputStreamReader(System.in);
isStdIn = true;
}
// Now process inp.
if (isStdIn)
inp.close();
} catch (Exception e) {
System.exit(1);
}
}
}
It selects either the file (if available) or the standard input stream for reading.
Often, the most easy way is to use Scanner:
Scanner scaner = new Scanner (System.in);

Categories