7
\$\begingroup\$

I implemented a simple version of echo(1) command utility. The program works as described in the man page: it writes to the standard output all command line arguments, separated by a whitespace and end with a newline. It can process the option -n that avoid to print the newline.

About my implementation, it is not complete, because it doesn't interpret common backslash-escaped characters (for example \n, \c, and so forth). i used a StringBuilder object to build the output string, because I'm not sure that the standard output is buffered. I also make some checks so the program can work without specifying any arguments.

You can compile the program with javac JEcho and run it with java JEcho <...>.

JEcho.java

/**
 * JEcho writes any command line argument to the standard output; each argument
 * is separated by a single whitespace and end with a newline (you can
 * specify '-n' to suppress the newline).
 *
 * This program doesn't interpret common backslash-escaped characters (for
 * exampe '\n' or '\c').
 */
public class JEcho {
    public static void main(String[] args) {
        boolean printNewline = true;
        int posArgs = 0;

        if (args.length > 0 && args[0].equals("-n")) {
                printNewline = false;
                posArgs = 1;
        }

        StringBuilder outputBuilder = new StringBuilder();

        for (; posArgs < args.length; posArgs++) {
            outputBuilder.append(args[posArgs]);
            outputBuilder.append(" "); // Separator.
        }

        // Remove the trailing whitespace at the end.
        int outputLength = outputBuilder.length();
        if (outputLength > 0)
            outputBuilder.deleteCharAt(outputBuilder.length() - 1);

        String output = outputBuilder.toString();

        if (printNewline)
            System.out.println(output);
        else
            System.out.print(output);
    }
}
\$\endgroup\$
  • \$\begingroup\$ can you explain a bit more about the purpose of JEcho? is it akademical or du you want to proof something? do you want to write n utility for your home computer? \$\endgroup\$ – Martin Frank Feb 15 '18 at 13:27
  • \$\begingroup\$ why don't you print the arguments directly? \$\endgroup\$ – Martin Frank Feb 15 '18 at 13:32
  • 1
    \$\begingroup\$ @MartinFrank I'm learning Java, so I'm reimplementing some utilities that I use frequently. This program is not production ready, it is only an exercise. \$\endgroup\$ – user146184 Feb 15 '18 at 13:33
  • \$\begingroup\$ @MartinFrank because I need to separate all arguments with a whitespace and because I don't know if the standard output is buffered. \$\endgroup\$ – user146184 Feb 15 '18 at 13:34
  • 2
    \$\begingroup\$ A standard POSIX echo doesn't interpolate any backslash escapes either, so this is a faithful implementation. \$\endgroup\$ – Toby Speight Feb 15 '18 at 16:25
5
\$\begingroup\$

If you're using Java 8, you can use StringJoiner.

/**
 * JEcho writes any command line argument to the standard output; each argument
 * is separated by a single whitespace and end with a newline (you can
 * specify '-n' to suppress the newline).
 *
 * This program doesn't interpret common backslash-escaped characters (for
 * exampe '\n' or '\c').
 */
public class JEcho {
    public static void main(String[] args) {
        boolean printNewline = true;
        int posArgs = 0;

        if (args.length > 0 && args[0].equals("-n")) {
                printNewline = false;
                posArgs = 1;
        }

        StringJoiner outputBuilder = new StringJoiner(" ");

        for (; posArgs < args.length; posArgs++) {
            outputBuilder.add(args[posArgs]);
        }

        String output = outputBuilder.toString();

        if (printNewline)
            System.out.println(output);
        else
            System.out.print(output);
    }
}
\$\endgroup\$
  • \$\begingroup\$ What are the differences between StringBuilder and StringJoiner? \$\endgroup\$ – user146184 Feb 15 '18 at 13:27
  • 1
    \$\begingroup\$ @ema-pe I accidentally forgot the " " argument. StringJoiner adds something between the values. \$\endgroup\$ – Solomon Ucko Feb 15 '18 at 13:55
  • \$\begingroup\$ Doesn't Java have a foreach, or doesn't have something similar to C# String.Join( separator, value ) where separator would be the " " and value the args? EDIT: I've seen that Java as a similar method, so why don't use it? \$\endgroup\$ – auhmaan Feb 15 '18 at 18:28
  • \$\begingroup\$ @auhmaan, the -n argument complicates things. \$\endgroup\$ – Solomon Ucko Feb 15 '18 at 21:13
2
\$\begingroup\$

as a matter of an excersice i would advise you to keep your parameters as List<String>...

public static void main(String[] args) {
    boolean printNewline = true;
    List<String> parameters = new ArrayList<>(Arrays.asList(args);
    if (args.length > 0 && isNewLine(args[0]) ) {
        printNewline = false;
        parameters.remove(0); //remove the first one
    }

    String output = parameters.stream()
        .collect(Collectors.joining(" ", "", printNewLine ? System.lineSeparator() : "")

    System.out.print(output);
}

NOTE: the method isNewLine() is not shown here - but you should consider using such a method to prevent a missing argument... think of -n, -N, /n, /N, all these parameters can be handle in the isNewLine-method...

\$\endgroup\$
  • 1
    \$\begingroup\$ I would push the ternary op as deep as possible: parameters.stream().collect(Collectors.joining(printNewLine ?"\n":",")) \$\endgroup\$ – Landei Feb 15 '18 at 13:49
  • \$\begingroup\$ man - formatting in stackjoverflow always tears me down =) haha \$\endgroup\$ – Martin Frank Feb 15 '18 at 13:49
  • \$\begingroup\$ very nice @Landei - would you please edit my post! \$\endgroup\$ – Martin Frank Feb 15 '18 at 13:50
  • 5
    \$\begingroup\$ This doesn't do the same as the question. Namely, printNewLine should print a line after the rest of the string, not as word separator. Then, the separator is always a whitespace, not ",". Fixing these is rather easy actually: Collectors.joining(" ", "", printNewLine ? System.lineSeparator() : "") and using System.out.print instead of System.out.println. \$\endgroup\$ – Olivier Grégoire Feb 15 '18 at 16:08
  • 3
    \$\begingroup\$ i have added your valuable input @OlivierGrégoire thank you so much for precising this requirement! - even though you tried to edit my post it was disapproved... very bad, considering the comments where i especially asked you to do so - anyway, keep up the good work & thanks again! \$\endgroup\$ – Martin Frank Feb 16 '18 at 11:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy