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);
}
}
-
\$\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– Martin Frank2018年02月15日 13:27:36 +00:00Commented Feb 15, 2018 at 13:27
-
\$\begingroup\$ why don't you print the arguments directly? \$\endgroup\$Martin Frank– Martin Frank2018年02月15日 13:32:23 +00:00Commented Feb 15, 2018 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– user1461842018年02月15日 13:33:04 +00:00Commented Feb 15, 2018 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– user1461842018年02月15日 13:34:43 +00:00Commented Feb 15, 2018 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– Toby Speight2018年02月15日 16:25:42 +00:00Commented Feb 15, 2018 at 16:25
2 Answers 2
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);
}
}
-
\$\begingroup\$ What are the differences between
StringBuilder
andStringJoiner
? \$\endgroup\$user146184– user1461842018年02月15日 13:27:10 +00:00Commented Feb 15, 2018 at 13:27 -
1\$\begingroup\$ @ema-pe I accidentally forgot the " " argument.
StringJoiner
adds something between the values. \$\endgroup\$Solomon Ucko– Solomon Ucko2018年02月15日 13:55:17 +00:00Commented Feb 15, 2018 at 13:55 -
\$\begingroup\$ Doesn't Java have a
foreach
, or doesn't have something similar to C#String.Join( separator, value )
whereseparator
would be the" "
andvalue
theargs
? EDIT: I've seen that Java as a similar method, so why don't use it? \$\endgroup\$auhmaan– auhmaan2018年02月15日 18:28:00 +00:00Commented Feb 15, 2018 at 18:28 -
\$\begingroup\$ @auhmaan, the
-n
argument complicates things. \$\endgroup\$Solomon Ucko– Solomon Ucko2018年02月15日 21:13:05 +00:00Commented Feb 15, 2018 at 21:13
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...
-
1\$\begingroup\$ I would push the ternary op as deep as possible:
parameters.stream().collect(Collectors.joining(printNewLine ?"\n":","))
\$\endgroup\$Landei– Landei2018年02月15日 13:49:40 +00:00Commented Feb 15, 2018 at 13:49 -
\$\begingroup\$ man - formatting in stackjoverflow always tears me down =) haha \$\endgroup\$Martin Frank– Martin Frank2018年02月15日 13:49:41 +00:00Commented Feb 15, 2018 at 13:49
-
\$\begingroup\$ very nice @Landei - would you please edit my post! \$\endgroup\$Martin Frank– Martin Frank2018年02月15日 13:50:17 +00:00Commented Feb 15, 2018 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 usingSystem.out.print
instead ofSystem.out.println
. \$\endgroup\$Olivier Grégoire– Olivier Grégoire2018年02月15日 16:08:03 +00:00Commented Feb 15, 2018 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– Martin Frank2018年02月16日 11:01:55 +00:00Commented Feb 16, 2018 at 11:01