So for an assignment at school I am required to make a program in java that manages some students at a college, the user may invoke a number of function, but I started by testing 'add'.
My prof recommends that I use input redirection, because I can easily test the program over and over, without much typing. Now here is the issue.
echo `< input.txt`
add Student Name 123 Street,City,Province,Postal Code q
#Input rediraction ate my newlines
cat input.txt
add
Student Name
Street,City,Province,Postal Code
q
#What I actually want to run
java -cp . TestCollege < input.txt #fail horribly
As you can see bash removes the newline characters I use to delimit my input, and thus my program crashes, because when you run it in interactive mode, Scanner.getLine() just blocks until input occurs.
Any idea how I can give my program the input with the newlines, it seems to work fine in windows "cmd" but not in "bash".
Could you try wrapping BufferedInputStream around System.in, because it can handle both cases: \r\n and \n; and I think that's where your problem lies.
Or rather, call useDelimiter(System.getProperty("line.separator")) on Scanner.
Well, you can see how bash does not eat the newlines running
$ wc -l < input.txt
Which I guess will give you the value you'd expect.
Related
I want some code in my program to run only if the user has input the character '*' at the command-line as a command-line argument. This is the code I've used:-
//myfile.java
import java.io.*;
public class myfile {
public static void main(String[] args) {
if(args[0].equals("*")){
//do stuff
System.out.println(args[0]);//added this line to see what exactly was being passed
}
}
}
When this program is executed at the command-line by entering:-
java myfile *
the output I'm expecting to see on the screen is the asterisk character, instead the output displayed is 'myfile.class'. Where am I going wrong? Why does Java change the asterisk to the .class file?
Also, note that the program worked perfectly the first four times I executed it and then started doing this!
Thanks in advance for your help.
Where am I going wrong?
The star character needs to be quoted or escaped. Run your java program like this:
java myfile "*"
or
java myfile \*
Why does Java change the asterisk to the .class file?
It doesn't. It is your shell that is doing it. It is shell file expansion ... or "globbing" as it is also called.
Run "ls *" or "echo *" and you will see that the same thing happens.
The command terminal already replaces the asterisk and java already gets the value that you see. I'd use any other character, that has no special meaning to the command terminal or otherwise you must escape the asterisk in your command.
Actually escaping arguments on Windows and especially in cmd.exe is non-trivial. This nice article explains it in detail: Everyone quotes command line arguments the wrong way :
the takaway for your case is: surround the asterisk with quotes.
Answer to your question in the comment:
Using the escape character worked! But I still don't get why it worked without the escape character the first few times
I am not sure, but maybe you run into this behavior: It makes a difference if the pattern can be expanded or not. For example, when I pass Test* as argument, then there are 2 cases to consider:
in the current folder there is a file called Test1.txt: then your java program will get Test1.txt as argument
when there are no matching files, your program will get Test* as argument
However, I am not sure, how this would apply to your case, since you only pass *: that should only work in an empty directory.
To capture the output of process in Groovy I use the following:
"command".execute().text
I want to do the same in Java, but all responses I found contain a lot of boilerplate code involving loops, BufferedReader, Scanner, etc.:
Get Command Prompt Output to String In Java
How to run Windows commands in JAVA and return the result text as a string
java runtime.getruntime() getting output from executing a command line program
Can I do the same thing within 1-2 lines of code? Maybe Guava or Apache have something to make life simpler?
I've managed to come up with the following two-liner:
Process process = Runtime.getRuntime().exec("command")'
String output = IOUtils.toString(process.getInputStream());
I am trying create a basic file system to imitate the terminal. I am currently stuck on getting the names after the command. My first thought was to use regex to parse the commands.
Examples of commands would be:
mkdir hello
ls
cd hello
However to account for many whitespaces an input could be mkdir hello. I was wondering if there is another way without using regex? Also I was curious to which method is faster? With or without regex?
You could try splitting the lines like
String[] tokens = line.split(" ");
And for basic commands, most likely your command will be at tokens[0] followed by arguments.
for(String current: line.split("\\s+"){
//do something.
}
Usually, regex is faster because you can compile it.
see java.util.regex - importance of Pattern.compile()?
(Internally, I think the JVM always compile the regex at some point, but if you do it explicitly, you can reuse it. I am not sure if the JVM is smart enough to reuse a compiled regex locally, maybe it is)
How do you read from and write to files passed on the command line using the < and > symbols?
This is the command: java Main < input.txt > output.txt
So I want to know what the code in the java file will look like. How do I reference these files?
Just to clarify, I can use files no problem if passed with: java Main input.txt output.txt
but I'm currently constrained to using the angle brackets.
Assuming that you are talking about Linux/Unix/Bsd ...
The < and > redirections are handled by the shell itself. By the time your Java application is called, the shell has already figured out what the pathnames resolve to, opened them, and connected them to the file descriptors used for System.in and System.out.
So you just code your program to read from System.in and write to System.out.
(The same principle applies if your application is part of a pipeline, and if FD #2 is redirected, that will be connected to System.err. The only thing that is not straightforward is if you do something unusual like this:
java Main < input.txt 3> output.txt
That will redirect FD #3 to a file. AFAIK, there is no simple way to write to FD's beyond 2 from Java.)
These operators mean that you want to read the input from input.txt and write the result to output.txt.
Following normal conventions, < is System.in and > is System.out. However, passing just a String to System.in probably does not do what you expect it to in this case
I run egrep using Java Runtime.exec()
String command = "egrep \'(Success|Loading\\.\\.\\.|Loaded : READY|Found a running instance)\' "+ instance.getPath() + "/log";
Runtime.getRuntime().exec(command);
The stdout is always null and stderr shows "egrep: Unmatched ( or (". but when I copy the command to shell and run, it returns the correct value.
The solution is pretty simple: (Success|Loading\\.\\.\\.|Loaded is not a valid regex.
You can't protect white space with quotes when using Process.exec(String). Always use the versions of exec() that take an array or, even better, use ProcessBuilder.
That way, you can pass each argument as a single Java String and spaces and other special characters won't create any problems.
The single quotes should not be escaped. You don't escape them on the command line, either, do you?