How to send a filename through batch & accept it in Java - java

Ok so I might have worded this wrong, it's a little difficult to explain. So here goes:
Main Goal: Call java triangle program through batch while also piping a list of testcase.txt files with input that must be sent to the java program to determine the triangle type. WITHOUT hard typing the file name into the java program.
Problem:Not sure how to accept the fileName to use in the java application from the batch command window.
Currently, I'm just using one text file to test with containing 3 numbers separated by a space. When running the java program by itself I can type the file path to the text file & everything works as intended. But alas I can't hard code or ask the user for that path since this should be setup by the batch file to call these 15 test case files to send to the program. The part of code I have now that I dont understand is this:
Scanner input = new Scanner(System.in);
String fileName = input.next();
Scanner reader = new Scanner (new File(fileName));
So I understand that input.next() is going to be asking for keyboard input how can I switch this from keyboard input to batch file input? If that makes sense.
Here is my batch file:
#ECHO off
set /P num1="Please enter file path: "
echo You entered %num1%
ECHO Checking for file...
if exist %num1% (
set num1=Congrats! I found the file!
C:\Users\josh\Documents\NetBeansProjects\Triangle\src\TriangleRebuild.java
) else (set num1=File does not exist)
echo %num1%
PAUSE
exit
Full Code:
/*
* Josh
Software Engineering
Structured Triangle Implementation in Java
*/
import java.io.*;
import java.util.*;
public class TriangleRebuild {
public static void main(String[] args) throws FileNotFoundException{
Scanner input = new Scanner(System.in);
String fileName = input.next();
Scanner reader = new Scanner (new File(fileName));
int a;
int b;
int c;
boolean isATriangle;
System.out.println("Enter 3 integers which are sides of a triangle: ");
a = reader.nextInt();
b = reader.nextInt();
c = reader.nextInt();
System.out.println("Side A is: " + a);
System.out.println("Side B is: " + b);
System.out.println("Side C is: " + c);
if((a < b + c) && (b < a + c) && (c < a + b)){
isATriangle = true;
}
else{
isATriangle = false;
}
if(isATriangle){
if((a == b) && (b == c)){
System.out.println("Triangle is Equilateral.");
}
else if((a != b) && (a != c) && (b != c)){
System.out.println("Triangle is Scalene.");
}
else{
System.out.println("Triangle is Isosceles.");
}
}
else{
System.out.println("Not a Triangle.");
}
if((Math.pow(c,2) == Math.pow(a,2) + Math.pow(b,2))){
System.out.println("Triangle is a right Triangle.");
}
else{
System.out.println("Triangle is not a right Triangle.");
}
}
}

You know that every main method is declared like this:
public static void main(String[] args) {...}
That args array represents command line arguments. That is, parameters you wrote on the java command line in your cmd window or your batch. So for example, if you have a line in your batch that says:
java TriangleRebuild abc.txt
Then inside the program, the array args will have the value { "abc.txt" }. You can access that by using args[0]. You have to make sure, of course, that args.length > 0 and that args[0] != null before you use it, just in case someone forgot to write the file name on the command line.
You can pass several file names in the command line.
java TriangleRebuild abc.txt def.txt hij.txt
And then your array will be: {"abc.txt","def.txt","hij.txt"} inside the program.
This way, you can pass argument from your batch to your Java and process them without interaction with the user.

Your best bet will likely be as follows: have the Batch file pipe the text file locations, as if they were input in a command line. Then, use those command line arguments to call the main method of your java class (simply invoke it like you would from the command line, with all of your batch input as the Args). Once inside the main method, do with them as you wish.

Related

How to create multiple directories?

I am new to programming and recently have tried to make a simple program to create multiple directories with names as I want. It is working but at the beginning, it is adding first "number" without asking me. After this, I can make as many folders as I want.
public class Main {
public static void main(String args[]) throws IOException{
Scanner sc = new Scanner(System.in);
System.out.println("How many folders do you want?: ");
int number_of_folders = sc.nextInt();
String folderName = "";
int i = 1;
do {
System.out.println("Folder nr. "+ i);
folderName = sc.nextLine();
try {
Files.createDirectories(Paths.get("C:/new/"+folderName));
i++;
}catch(FileAlreadyExistsException e){
System.err.println("Folder already exists");
}
}while(number_of_folders > i);
}
}
If I chose to make 5 folders, something like this is happening:
1. How many folders do you want?:
2. 5
3. Folder nr. 0
4. Folder nr. 1
5. //And only now I can name first folder nad it will be created.
If it is a stupid question, I will remove it immediately. Thank you in advance.
It's because your sc.nextInt() in this line :
int number_of_folders = sc.nextInt();
doesn't consume last newline character.
When you inputted number of directories you pressed enter, which also has it's ASCII value (10). When you read nextInt, newline character haven't been read yet, and nextLine() collect that line first, and than continue normally with your next input.
In this case, you can just use the mkdir part of the File class as so:
String directoryName = sc.nextLine();
File newDir = new File("/file/root/"+directoryName);
if (!newDir.exists()) { //Don't try to make directories that already exist
newDir.mkdir();
}
It should be clear how to incorporate this into your code.

Running Java program via Command Prompt with input and output files

I have a program that is supposed to take inputs from the commandline and direct them to standard input and direct the output to standard output. The code supposed to be entered into the commandline is meant to look as follows:
java package.sub.Calc < input-file > output-file
or
echo some inputs to the calculator | java
package.sub.Calc
But I can't seem to get it to work correctly. The goal is to be able to pass a text file into the program or write your math problems right there on the command line and pipe it in.
The program runs correctly for
java -cp . package.sub.Calc
and then having the user type in their problem and hitting enter.
If I have a file named input.txt and want to call it from the command line and have the answers print out in the commandline (program is designed to System.out.println) how would I be entering this information in?
My current code implements a Scanner for System.in. Would I have to use anything else to get this to work? I am new to running anything in the command prompt and can't seem to get it to work.
Any help is greatly appreciated.
My code:
public static void main(String[] args) {
Calc calc = new Calc();
Scanner sc = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
String input = "";
List<String> strs = new ArrayList<>();
ArrayList<String> tokens;
while (sc.hasNextLine()) {
String line = sc.nextLine().trim();
if (line.isEmpty()) {
for (String s : strs) {
sb.append(s);
input = sb.toString();
}
tokens = new ArrayList<>(Arrays.asList(input.split(" ")));
//call calculate and reset
calc.calculate(tokens);
strs.clear();
tokens.clear();
sb.setLength(0);
input = "";
} else if (line.length() == 1) {
strs.add(" ");
strs.add(line);
strs.add(" ");
//manual user exit case
} else if (line.equals("EXIT")){
System.exit(0);
}else {
strs.add(line);
}
}
}
You seem to have 2 problems.
1) You're including the -cp commandline option when you run the program manually, but not when you try and read from the input. You need it in both cases - that's telling java where to find your class file.
2) The way you are handling your input doesn't match the input you're passing in.
You only call calculate when you receive an empty line ( if(line.isEmpty()) ), but something like
echo some inputs to the calculator | java -cp . package.sub.Calc
doesn't ever produce a blank line.
You either need to do:
printf "%s\n\n" "some inputs to the calculator" | java -cp . package.sub.Calc
or change the condition that triggers a calculate (probably by invoking it outside of the while loop).
your input is received in your main method. public static void main (String[] args). The args array is the array which will receive your input parameters IF you have ran your program as java -cp . <main_class_pat> <arg0> <arg1> ...
Make sure your args array has desired length ... and if so, your input file would be at arg[0]

Stuck on a Java instruction

Question:
The commands should be passed in to the program as a file with one instruction per line. The English instructions are in the file commands in english.txt and the Spanish instructions are in the file commands in spanish.txt. You call the program by the passing in the instructions as follows:
java ConsoleRobot < commands_in_english.txt
or
java ConsoleRobot < commands_in_spanish.txt
I don't get what the question is asking? Does it want me to have the commands I enter to go to the english text file or does it want me to have all my commands stored in the english text file?
Here is a link to the full question. I got all of it except the last part. Here is a link to my Java file.
import java.util.Scanner;
public class ConsoleRobot extends SmarterRobot {
public static void main(String [] args) {
World yard = new World();
SmarterRobot ringo = new SmarterRobot();
yard.add(ringo,5,4);
yard.addBeeper(5,9);
yard.addBeeper(4,5);
yard.addBeeper(9,4);
yard.addBeeper(9,5);
Scanner scan = new Scanner(System.in);
System.out.println("Enter a command: | Introduzca un comando:");
String command = scan.nextLine();
command = command.toLowerCase();
while (!command.equals("stop") && !command.equals("detener")) {
if ( command.equals("forward") || command.equals("adelante")) {
System.out.println("How far should the robot move?");
int input = scan.nextInt();
ringo.moveNumOfTimes(input);
} else if ( command.equals("right") || command.equals("derecha"))
ringo.turnRight();
else if ( command.equals("left") || command.equals("izquierda")
ringo.turnLeft();
else if ( command.equals("collect") || command.equals("recoger"))
ringo.pickBeeper();
else if ( command.equals("drop") || command.equals("soltar"))
ringo.putBeeper();
System.out.println("Enter a command: | Introduzca un comando:");
command = scan.nextLine();
}
System.out.println("Finished | Terminado");
}
}
You don't need to do any code to accept the file passed with the < operator. As Majora320 wrote, the < operator renders the file to the standard input. In other wrods, your application will read the commands from the file as if it would have been entered from the keyboard.
The problem is with the scan.nextLine() call. This reads a whole line, and that makes impossible processing commands with parameter, e.g. forward 10 since you read in the whole line, not only the command.
The example below reads first a string (in.next()), and may continue with reading the parameter (in.nextInt()) if a command is expected to have a parameter. But it does not read any parameters for the stop command.
public class Robot {
public static void main(final String[] args) {
final Scanner in = new Scanner(System.in);
while (in.hasNext()) {
final String command=in.next();
if (command.equals("forward")) {
final int distance=in.nextInt();
System.out.println("Forwarding "+distance);
}
if (command.equals("stop")) {
System.out.println("Stopping");
}
}
}
}
The other little problem is that you're keep on reading the input until getting a stop command. This means that command files with no ending stop will not stop your application. It is safer to read until there is something to read, i.e. use while (in.hasNext()) to keep on reading.
Note how indentation and empty lines makes the code more readable, and much easier to follow.
The < operator (At least on the *nix terminal) is for passing the text from a file into the stranded input of a program. For example, grep "hello" < myfile.txt is exactly the same as cat myfile.txt | grep "hello". Basically, < is an abbreviation for running cat file | command. So what java ConsoleRobot < commands_in_english.txt means is pass all the lines in commands_in_english.txt to the stranded input of the ConsoleRobot program. That means you just write the instructions to the file and then run the command.

How do I ask a user for a input file name, and then use that file name?

I am trying to ask the user for the name of their file, then I am going to scan the file to see how many indices are in the file, and then put it in an array and go from there.
Here is my code:
import java.util.*;
import java.io.*;
public class TestScoresAndSummaryStatistics {
public static void main(String[] args) throws IOException {
int scores;
int indices = -1;
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter the name of the file");
String fileName = keyboard.next();
//I believe something is wrong here, am I incorrectly bring inputFile into new File?
File inputFile = new File(fileName);
Scanner data = new Scanner(inputFile);
while (data.hasNext()) {
indices++;
}
System.out.println("There are: " + indices + "indices.");
}
}
I believe something went wrong with the = new File(filename); part: maybe because I didn't have quotes, but I'm not exactly sure. How can I fix this?
Solution:
Change
while (data.hasNext()) {
indices++;
}
to
while (data.hasNext()) {
indices++;
data.next();
}
Explanation:
You want to increment indices for every line. To achieve this, you should go to the next line and check if there are other available lines. Q: How can you go to the next line ? A: data.next();
E.g. - file.txt:
Your approach - bad:
Step 1
line a <--- here you are
line b
line c
Step 2
line a <--- here you are
line b
line c
...
data.hasNext() will be true forever because you will be on the first line at every step => infinite loop
Correct approach:
Step 1
line a <--- here you are
line b
line c
Step 2
line a
line b <--- here you are
line c
Step 3
line a
line b
line c <--- here you are
In this case data.hasNext() will return true only 3 times, then it will return false ( the file doesn't have any line after the 3rd line )
You only check if there is data in Scanner but you never consume it.
The java.util.Scanner.hasNext() method Returns true if this scanner has another token in its input. This method may block while waiting for input to scan. The scanner does not advance past any input.
The below code will never end if there is any data in file, you increase your counter with out reading the data.
while (data.hasNext()) {
indices++;
}

Java -- Closing Scanner and Resource Leak

I'm learning Java and working on some projects for fun. One issue that I have run in to is that when I use a Scanner object Eclipse warns me that:
Resource Leak: 'scan' is never closed.
So, I added a scan.close(); at the end of my code and that takes care of the warning.
The problem comes in because I have other classes in the same package that also use scanner objects and and Eclipse tells me to close scanner in those classes respectively. However, when I do that it seems like it closes ALL of the scanner objects and I get errors during run time.
Here is an example of what causes the error:
import java.util.Scanner;
public class test2 {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
int test = 0;
do {
//Do stuff
test = scan.nextInt();
System.out.println(test);
scanTest scanTest = new scanTest();
scanTest.test();
} while (test != 0);
scan.close();
}
}
import java.util.Scanner;
public class scanTest {
public void test() {
Scanner scanner = new Scanner(System.in);
int blah = scanner.nextInt();
System.out.println(blah);
scanner.close();
}
}
After scanner is closed in the scanTest class and the do loop in test2 is entered again an error occurs at the line test = scan.nextInt();
I tried moving the creation of the scanner object into the do loop just to make a new object every time as well but the error still occurs.
Not sure why this is happening or how I can make sure all my I/O objects are closed out without running into problems.
One post I came across mentioned that when System.in is closed I cannot be re-opened. If this is the case would I just need to make sure a scanner object with System.in is closed at the very end of the program and #suppress all of the other scanner warnings in other classes? Or would that still leave all those scanner objects open (bad)?
First, this is no memory leak.
Second, when you close a stream wrapper, the default implementation is for it to close the stream that it wraps. This means that the first time you close your Scanner (as it is written), yes, you close System.in.
In general, one would like to avoid closing System.in if they were meaning to read from System.in again. The best way to go about this depends on your program.
One might copy the information from System.in into a buffer of some sort and then scan the buffer. One might not close the Scanner, reusing it in other locations. One might even de-reference the Scanner for garbage collection and create multiple new Scanners on System.in.
These solutions are not all equivalent, some are considered much better than others; but, it all depends on the calling program. Experiment with a few, and if you run into a problem, open a new StackOverflow question where you show the relevant portions of your code, a description of the problem, the example input, and the wrong output (along with the desired output).
Good luck.
Yes, when you close a scanner you will be closing the underlying stream (in this case System.in). To avoid this, either create a global variable of scanner which can be used by all classes or have a central point for shutting down the scanner (just before the program exits would be ideal)
Don't name all your scanners the same. If you have multiple in one thing like this:
import java.util.Random;
import java.util.Scanner;
public class DayThree {
public static void main(String[] args) {
**Scanner textScanner = new Scanner(System.in);**
// boolean operands
// String(or objects) .equals() "this".equals("that") false
// primitive data types == 'a'=='a' -> true 5==6 false
// != 'a'!='a' -> false 5!=6 true
// ! !(true) -> false !(false) true
// > 5 > 4 -> true 'a' > 'b' false
// < 5 < 4 -> false
// <=
// >=
// && -> and 5 < 6 && 7 > 10 -> false
// if either side of and is false the outcome is false
// || -> or 5 < 6 || 7 > 10 -> true
// if either side of or is true the outcome is true
//System.out.println(!(5 < 10) && (7>3) || (true && false || true));
/* <-- this is a multi line comment
System.out.println("What is the most amazing show on tv this week? ");
String show = textScanner.nextLine().toLowerCase(); //this is case sensitive
show = show.toLowerCase(); // changes the strng to a lowercase version
show = show.toUpperCase();
if(show.equalsIgnoreCase("game of thrones")){ // .equalsIgnoreCase( ignores caps/lower)
System.out.println("Yes it is!");
}
else{
System.out.println("You are wrong.");
System.out.println(show + " is clearly inferior to Game of Thrones.");
}
System.out.println("Who is your favorite character in " + show + ".");
String character = textScanner.nextLine().toLowerCase();
if(character.contains("dragon")){
System.out.println("CGI magic is so cool!");
}
else if(character.contains("lanister")){
System.out.println("Wrong house.");
}
else{
System.out.println(character + "is pretty cool I guess...");
}
*/
// asdf alternate multi line comment use ctrl + / on highlighted text.
// doing this a second time undoes the comment
// sdaf
// asdf
// asdf
// asdf
// 1. ask about favorite something (pet)
// 2. save that into a string all lowercase
// 3. have a series of if else (x3) and else statements about the something
//NOTE: DO NOT END CONDITIONALS WITH ; example: if(boolean); IS WRONG.
**Scanner numScanner = new Scanner(System.in);** // the variable tells you what to use it for
Random rand = new Random(); // this makes a new random object
System.out.println("Pick a number.");
int num = numScanner.nextInt();
int sNum = rand.nextInt(9) + 1; // gives me a random num between 1-10
// nextInt(bound)gives you a num from 0-bound
//adding one gives you a num from 1 - bound + 1
if(num > sNum){
System.out.println("Too high");
System.out.println("The number was " + sNum);
}
else if(num < sNum){
System.out.println("Too low");
System.out.println("The number was " + sNum);
}
else{
System.out.println("Wow are you psychic? ");
}
textScanner.close();
numScanner.close();
}//main method
}
Put the *scanner name goes here*.close(); for each one of your scanners. If they all have the same name then change the ones that do something different from and other scanner.

Categories

Resources