user1079065
user1079065

Reputation: 2215

Printing formatted output in java with special characters

I encountered following code and could not figure out how it works.

System.out.printf("17%1$s","16%1$s");
System.out.printf("17%1$s","16%1$s","18%1$s");

Whatever you put for 1st two the same numbers are printed You can add how many ever parameters to printf the output is same.

Output produced is : 1716%1$s

System.out.printf("17%1$s","16%4$s","17%1$s","20%1$s");

output is : 1716%4$s So I realized that it doesn't process after the 2nd parameter.

If I change the code to System.out.printf("17%5$s","16%4$s","17%1$s","20%1$s");

I get java.util.MissingFormatArgumentException ???

How is the working exactly? What are these parameters? Thanks in advance

Upvotes: 2

Views: 2406

Answers (3)

ajb
ajb

Reputation: 31699

System.out.printf("17%1$s","16%1$s");

The first argument to printf is the format string. Any remaining arguments are the data to print.

The format string here is "17%1$s". This contains some characters that should appear literally, i.e. the two characters "17". Then it contains a format specifier that indicates how one of the arguments should appear. Format specifiers always begin with %.

This particular specifier is broken down like this:

%   - tells printf that a format specifier is coming up
1$  - tells it to use the first argument to printf (not counting the format 
      string itself--so it's really the second argument)
s   - tells it that the argument is expected to be a String

So the output is "17", followed by the argument, which is the string "16%1$s". Although the argument also looks like it has format specifiers, it really doesn't. All arguments except the first are just data.

If you add other arguments, they don't affect the output of printf since there are no format specifiers in the format string (i.e. the first argument) that tell printf to use them.

System.out.printf("17%5$s","16%4$s","17%1$s","20%1$s");

Here, the format string tells printf to use the fifth data argument, not counting the format string itself. Since there is no fifth data argument (there are only three), you get an exception.

(P.S. You don't need to include the 1$ in the format string. If it's missing, then the first format specifier automatically uses the first data argument, the second format specifier uses the second data argument, and so on.)

The syntax of a format string is described here.

Upvotes: 2

morgano
morgano

Reputation: 17422

System.out.printf(...) Follows the syntax of the Formatter class, it doesn't process recursively. First parameter is the one where the replacements are to be done, the rest are just values to replace in the first string.

The specifiers for replacement follow this pattern:

%[argument_index$][flags][width][.precision]conversion

In the case of System.out.printf("17%1$s","16%1$s"); it replaces "%1$s" in the first string with "16%1$s", "%1$s" means "the first parameter following the syntax string (1$), whose convertion is a string type (the 's' at the end)") if your method contains more parameters than those specified in your first string, they are just ignored.

more info here: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html

Upvotes: 1

Deegriz
Deegriz

Reputation: 1925

Take a look at this documentation:

Formatting Numeric Print Output

Formatting Output

What you have there is fairly similar to Java's Date formatting (albeit unrelated). The table in that link should make it more clear for you.

EDIT: Sorry, forgot another link which is more important

Upvotes: 1

Related Questions