Change a program to accept command line arguments - java

I have the following code and would like to modify it to accept command line arguments instead of reading a file using scanner. Can you point me to some change I need to make in the code in order to do so ? Any help is appreciated. I will have a file called prgm.cmd and will execute it on UNIX as follows. prgm.cmd is the actual argument !
java Commander prgm.cmd
right now I am only able to have the program work by using
java Commander < prgm.cmd
CODE
import java.util.Scanner;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class Commander
{
public static void main(String[] args)
{
Map<String,Integer> expression = new HashMap<String,Integer>();
ArrayList<String> list = new ArrayList<String>();
Scanner sc = new Scanner(System.in);
while(true)
{
list.add(sc.nextLine());
if(!sc.hasNextLine()) break;
}
ArrayList<String> tokens = new ArrayList<String>();
ArrayList<String> PRINT = new ArrayList<String>();
for(String element : list) {
StringTokenizer st = new StringTokenizer(element);
if(!element.startsWith("PRINT")) {
while(st.hasMoreTokens()) {
tokens.add(st.nextToken());
}
expression.put(tokens.get(0),Integer.parseInt(tokens.get(2)));
tokens.clear();
} else {
while(st.hasMoreTokens())
PRINT.add(st.nextToken());
System.out.println(expression.get(PRINT.get(1)));
PRINT.clear();
}
}
}
}
SAMPLE COMMAND FILE: PRGM.CMD
A = 6
C = 14
PRINT C
B = 12
C = 8
PRINT A
OUTPUT
14
6

public static void main(String[] args)
// ^^^^^^^^^^^^^
When you run your program with something like:
java progname arg1 arg2
the arguments appear in the string array handed to main(). You just extract them from there and do what you need.
The following small (but complete) program shows this in action. It will echo back your arguments, one per line:
public class Test {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++)
System.out.println (args[i]);
}
}
That's to get the commands as arguments to the program.
If, instead, you want to still have the commands in a file and just supply the file name to the program, you simply need to change your scanner to use a file based reader rather than System.in. The following program accepts a file name argument then echos it to the screen:
import java.io.FileInputStream;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
try {
Scanner sc = new Scanner (new FileInputStream(args[0]));
while (sc.hasNextLine())
System.out.println (sc.nextLine());
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
You can even make it selectable, like UNIX filter programs using - to indicate standard input.
If you want to use a file if provided but revert to standard input if not, you can do something like:
Scanner sc;
if (args.length > 0)
sc = new Scanner (new FileInputStream(args[0]));
else
sc = new Scanner (System.in);
// Now just use scanner as before

Related

Need to get a line from a file onto queue and not the whole file text

I'm having trouble properly getting one line of text at a time from a file onto a queue without taking the whole file into the queue. For example, I'd like only Write a program that reads a Java source file as an argument and produces an index of all identifiers in the file. For each identifier, print all lines in which it occurs. For simplicity, we will consider each string consisting only of letters, numbers, and underscores an identifier.
Declare a Scanner in for reading from the source file and call in.useDelimiter("[^A-Za-z0-9_]+") Then each call to next returns an identifier.
public class Main { to get added to the queue but instead the whole file text is put into the queue instead of a line at a time. Sorry if my question is unclear
// Write a program that reads a Java source file as an argument and produces an index of all
// identifiers in the file. For each identifier, print all lines in which it occurs. For simplicity,
// we will consider each string consisting only of letters, numbers, and underscores an identifier.
// Declare a Scanner in for reading from the source file and call in.useDelimiter("[^A-Za-z0-9_]+").
// Then each call to next returns an identifier.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class E_15 {
public static void main(String[] args) throws FileNotFoundException
{
// get scanner input from file
Scanner fileInput = new Scanner(new File ("C:/Users/ramir/IdeaProjects/PA_7/src/Main.java"));
Queue<String> test = new LinkedList<String>();
ArrayList<String> phrase = new ArrayList<String>();
/*
List<String> result = new ArrayList<String>();
Scanner s = new Scanner(is);
s.useDelimiter(delimiter);
*/
// Iterates till end of file
while (fileInput.hasNextLine())
{
// Here is the issue. Data will end up
// containing the whole file instead of only that line
String data = fileInput.nextLine();
Scanner in = new Scanner(data);
in.useDelimiter("[^A-Za-z0-9_]+");
// I believe around here or before is the issue that I'm having.
// It adds all the file instead of only that line
// Also trying to figure out how to display each line that it's displayed on
// What the first one should look like for example
// 0: public occurs in:
// public class Main {
// public static void main(String[] args) {
//System.out.println(data);
test.add(data);
while(in.hasNext())
{
// Getting each phrase/word into ArrayList
String token = in.next();
phrase.add(token);
}
in.close();
}
int index = 0;
// This part works fine
for(String num : phrase)
{
// printing the key
System.out.println(index + ": " + num + " occurs in:");
// printing the values
// This to print out what
for(String line : test)
{
System.out.println(line);
}
System.out.println();
++index;
}
}
}
// Just java class get file front
// This is fine
public class Main {
public static void main(String[] args) {
int a_1 = 100;
System.out.println(a_1);``
}
}
I'd like it to only show System.out.println(a_1) because the line that's it's on See This
. I'm also have trouble printing it in all the lines that occur.
import java.io.*;
import java.util.Scanner;
public class ReadLineByLineExample2
{
public static void main(String args[])
{
try
{
//the file to be opened for reading
FileInputStream fis=new FileInputStream("Demo.txt");
Scanner sc=new Scanner(fis); //file to be scanned
//returns true if there is another line to read
while(sc.hasNextLine())
{
System.out.println(sc.nextLine()); //returns the line that was skipped
}
sc.close(); //closes the scanner
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Try studying the above code. I hope it will help. Otherwise, you might need to open this link for more detail.

Reading from a file and excluding words using Scanner

Im currently trying to write a program that counts the amounts of times different words are being used in a text, and then attach the values to a hashmap. In the main part of the program i use a scanner to read in the file with the text, and i initiate the GenWordCtr with another scanner thats supposed to read in a file with words i want excluded (words like "this, her, that"). Ive made sure that the string sent to op.process is lowercased, however when i run the program it still adds all the values that i want excluded from the statistics. What am i doing wrong? I know the main program works, ive tried it with single words.
TLDR - i want words excluded using a scanner to read in a text, for some reason they arent being excluded in the "process" operation of my program.
package textproc;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
public class Holgersson {
public static final String[] REGIONS = { "blekinge", "bohuslän", "dalarna", "dalsland", "gotland", "gästrikland",
"halland", "hälsingland", "härjedalen", "jämtland", "lappland", "medelpad", "närke", "skåne", "småland",
"södermanland", "uppland", "värmland", "västerbotten", "västergötland", "västmanland", "ångermanland",
"öland", "östergötland" };
public static void main(String[] args) throws FileNotFoundException {
Scanner s = new Scanner(new File("../lab1/nilsholg.txt"));
Scanner stopwords = new Scanner(new File("undantagsord.txt"));
s.useDelimiter("(\\s|,|\\.|:|;|!|-|\\?|'|\\\")+"); // se handledning
TextProcessor gen = new GeneralWordCounter(stopwords);
while (s.hasNext()) {
String word = s.next().toLowerCase();
gen.process(word);
}
s.close();
gen.report();
}
}
package textproc;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class GeneralWordCounter implements TextProcessor {
private Map<String, Integer> m;
private Scanner excep;
GeneralWordCounter(Scanner r){
Map<String, Integer> m = new HashMap<String, Integer>();
this.m = m;
excep = r;
}
#Override
public void process(String word) {
// TODO Auto-generated method stub
boolean bin = false;
while(excep.hasNext() && bin == false) {
if(word.equals(excep.next().toLowerCase())) {
bin = true;
}
}
if(!bin) {
if(m.containsKey(word)) {
m.put(word, (m.get(word) + 1));
}
else {
m.put(word, 1);
}
}
}
#Override
public void report() {
// TODO Auto-generated method stub
for(String key : m.keySet()) {
if(m.get(key) >= 200) {
System.out.println(key + " - " + m.get(key));
}
}
}
}
You are using same Scanner instance for stopwords inside the loop, which might be getting exhausted within few number of below loops.
TextProcessor gen = new GeneralWordCounter(stopwords);
while (s.hasNext()) {
String word = s.next().toLowerCase();
gen.process(word);
}
Imagine this way, you have started above loop and passed the Scanner instance and when you called process method it started loop for word and reached to end of the file for second Scanner. Now, in the next loop you again called process method but this time pointer will be already at the end of the file as you are using same instance. So, you won't get expected output.
Instead, you need to create new instance of Scanner for each process method call.
public void process(String word) {
Scanner excep = new Scanner(new File("undantagsord.txt"));
// your code.

Java Pass an int through Command

public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new FileReader(args[1]));
String co = sc.next();
coup = Integer.parseInt(co);
I get a FileNotFoundException when I try to pass an int into the second argument in command line. This is only part of the code, a text file is passed as args[0]. However, I can't figure out how to pass a simple integer, only text files.
public static void main(String[] args) throws Exception
{
Scanner scan = new Scanner(new FileReader(args[0]));
int integerFromCM = Integer.parseInt(args[1]);
}
You state that a text file is the first argument (args[0]) so assign that in the scanner and when grabbing the integer all you need to do is send args[1] into Integer.parseInt method. You are getting the exception because you are assigning a FileReader object with the file name of the integer passed in.
You can't pass an int, but you can parse one:
public static void main(String[] args) {
String filename = args[0];
int i = Integer.parseInt(args[1]);
// ...
}
If you are getting a FileNotFoundException, one easy way to debug it is:
File file = new File(filename);
System.out.println(file.getAbsolutePath());
and it will be obvious where the problem lies, which is almost always the current directory of the application is not what you think it is.
Reviewing your code it reads as follows:
Create a Scanner to read the file in the first command line argument
Get the first integer from that Scanner as a String
Parse that String to an int
It is clearly sequenced to require a file from the first argument and that looks like it is intended.
Create a file called number.txt:
42
NumberPrinter.java:
import java.io.Scanner;
import java.io.FileReader;
public final class NumberPrinter {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(new FileReader(args[1]));
String numberInFile = scanner.next();
int number = Integer.parseInt(numberInFile);
System.out.println(number);
}
}
Run as follows:
java NumberPrinter number.txt
And it will print:
42
Alternatively if you intend to parse an int directly from the command line parameters try:
public final class NumberPrinterDirect {
public static void main(String[] args) throws Exception {
int number = Integer.parseInt(args[0]);
System.out.println(number);
}
}
NumberOrFilenameAwkward.java:
import java.io.Scanner;
import java.io.FileReader;
public final class NumberOrFilenameAwkward {
public static void main(String[] args) throws Exception {
int number;
try {
number = Integer.parseInt(args[0]);
} catch (NumberFormatException thisIsVeryUgly) {
Scanner scanner = new Scanner(new FileReader(args[1]));
String numberInFile = scanner.next();
number = Integer.parseInt(numberInFile);
}
System.out.println(number);
}
}
That is a terrible solution and screams for using a command line parsing library like JewelCLI or commons-cli to solve it cleanly.

Scanning in file

I'm trying to scan the following sentences into my Java program as strings:
The cat in the hat
The cat sat on the mat
Pigs in a blanket
and then read it into a list using whileloop and hasNextLine()method.
My problem is that I am unsure how to read this in as it is not a designated text file and I must utilizeargs [0]
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.ArrayList;
public class Scan {
public static void main(String[] args) throws FileNotFoundException{
//Opens a scanner into the file
File file = new File( args [0] );
try (Scanner scan = new Scanner(file))
{
ArrayList<String> list = new ArrayList<String>();
while(scan.hasNextLine())
{
list.add(scan.nextLine());
}
}
}
}
If you're just trying to output the list, use a for each style loop is the fastest way to check if you're doing it right.
for (String val : list)
{
System.out.println(val);
}
I think you should replace your existing code with the one below:
ArrayList<String> list = new ArrayList<String>();
Scanner scan = new Scanner(System.in);
while (scan.hasNextLine()) {
list.add(scan.nextLine());
}
scan.close();
Use System.in instead of new File(args[0]). System.in reads from the standard input (i.e. whatever is entered in with the keyboard). This should work both on an IDE and with command line input.
I hope this helps.

Scanner is not working on StringBuilder

I wrote a program that must take input from a file and extract only text from it while saving its contents into an array. My text file contents are:
There is some!text.written%in
the FILE[That]=Have+to`be==separated????
And what I have tried to code is:
public static void main(String[] args) throws FileNotFoundException, IOException {
BufferedReader file = new BufferedReader(new FileReader("mfile.txt"));
List<String> list = new ArrayList();
String str;
StringBuilder filedata = new StringBuilder();
Scanner toknizer = new Scanner(filedata.toString());
while((str=file.readLine())!=null){
filedata.append(str);
}
toknizer.useDelimiter("[^a-z]");
while(toknizer.hasNext()){
list.add(toknizer.next());
}
System.out.println(list);
}
at this time I only want to extract text that is written in small alphabets. But the program is printing out an empty list. Debugging revealed that toknizer.hasNext() is returning false in while(toknizer.hasNext()).
What is wrong? Am I using wrong regular expression? I got the idea of using [^a-z] from here.
Scanner toknizer = new Scanner(filedata.toString());
You just created a Scanner around an empty string.
That's not going to have any tokens.
Strings are immutable; appending to the StringBuilder later does not affect the existing String instance you passed to the Scanner.
Why not just do it like this?
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public static void main(String[] args) {
List<String> list = new ArrayList<String>(); // If List is generic then ArrayList should be too
Scanner input = null;
try {
input = new Scanner(new File("mfile.txt"));
} catch(Exception e) {
System.out.println(e.getStackTrace());
}
input.useDelimiter("[^a-z]");
while(input.hasNext()) {
String parse = input.next();
if(!parse.equals("")) {
list.add(parse);
}
}
System.out.println(list.toString());
}
Now you don't have to use a BufferedReader, FileReader or a StringBuilder.

Categories

Resources